Merge remote-tracking branch 'privilege/develop' into develop
This commit is contained in:
commit
bf26f2c087
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed 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.
|
|
@ -0,0 +1,95 @@
|
||||||
|
ch.eitchnet.privilege
|
||||||
|
==================
|
||||||
|
|
||||||
|
[![Build Status](http://jenkins.eitchnet.ch/buildStatus/icon?job=ch.eitchnet.privilege)](http://jenkins.eitchnet.ch/view/ch.eitchnet/job/ch.eitchnet.privilege/)
|
||||||
|
|
||||||
|
Overview
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Privilege is a light weight library to secure access or grant privileges to
|
||||||
|
users in an application. Privilege allows a developer to secure the application
|
||||||
|
in different levels of the application providing API's for different
|
||||||
|
contexts.
|
||||||
|
|
||||||
|
Privilege is implemented in the Java language and is light weight in that it has
|
||||||
|
no external dependencies other than a Java runtime environment version 6. Since
|
||||||
|
the JRE 6 has an LDAP implementation it is possible to store Privilege data in
|
||||||
|
a LDAP repository with only the Privilege JAR.
|
||||||
|
|
||||||
|
Privilege is distributed under the GNU Lesser General Public License on
|
||||||
|
Github.com and can be downloaded at
|
||||||
|
|
||||||
|
https://github.com/eitchnet/ch.eitchnet.privilege
|
||||||
|
|
||||||
|
The main developer is Robert von Burg <eitch@eitchnet.ch> who also maintains the
|
||||||
|
Github repository. He is available for all questions regarding Privilege
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
=======================================================================
|
||||||
|
In some cases a developer might want to restrict access to an application
|
||||||
|
depending on the role which an authenticated user has. In other cases the
|
||||||
|
developer would need a more finely grained control by restricting access to a
|
||||||
|
certain object, or a certain method call.
|
||||||
|
|
||||||
|
We were looking for an API which would allows us to restrict access to a given
|
||||||
|
object in different ways. For instance it was our intention to not simply
|
||||||
|
restrict access to a specific object type, or instance, but to restrict access
|
||||||
|
to an instance of the object if it had fields set to a specific value.
|
||||||
|
|
||||||
|
Evaluations on existing libraries which implement access restriction did not
|
||||||
|
provide an API which suited our needs or which were not easily implemented, thus
|
||||||
|
leading to the design of Privilege.
|
||||||
|
|
||||||
|
Design Goals
|
||||||
|
=======================================================================
|
||||||
|
When a developer needs to implement access restriction an application there are
|
||||||
|
different questions which the developer will ask:
|
||||||
|
- Does the user have a specific role?
|
||||||
|
- Does the user have a specific privilege i.e. is the user allowed to perform a
|
||||||
|
specific action?
|
||||||
|
- Is a user allowed to access a specific type of object?
|
||||||
|
- Is a user allowed to access a specific instance of a type?
|
||||||
|
- Is a user allowed to access a field on a specific object?
|
||||||
|
|
||||||
|
Privilege's design goals are to allow the developer to answer these questions
|
||||||
|
with an API which does not mean implementing a lot of additional project
|
||||||
|
specific code.
|
||||||
|
|
||||||
|
Further in Privilege it should be possible to perform the normal CRUD functions:
|
||||||
|
- Create users, roles, privileges, etc.
|
||||||
|
- Read existing users, roles, privileges, etc.
|
||||||
|
- Update users, roles, privileges, etc.
|
||||||
|
- Delete users, roles, privileges, etc.
|
||||||
|
|
||||||
|
It should be possible to store Privilege's data in different databases,
|
||||||
|
depending on the application. For example it should be able to store the data in
|
||||||
|
XML files, in a LDAP directory and so forth.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
The current documentation, though a bit outdated, can be found in the docs/
|
||||||
|
directory of the Repository
|
||||||
|
|
||||||
|
Compiling
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Privilege is a Maven3 project and can be built by simply performing the
|
||||||
|
following command:
|
||||||
|
|
||||||
|
$ mvn compile
|
||||||
|
|
||||||
|
Using
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
To use Privilege see the ch.eitchnet.privilege.test.PrivilegeTest.java class
|
||||||
|
which contains a few test cases including showing how to load Privilege.
|
||||||
|
|
||||||
|
This documentation is still in need of more work, but for any questions please
|
||||||
|
don't hesitate to write an e-mail to the developer and we'll find a solution.
|
||||||
|
|
||||||
|
Switzerland, the 29. July 2012
|
||||||
|
Robert von Burg
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Privilege>
|
||||||
|
|
||||||
|
<Container>
|
||||||
|
|
||||||
|
<Parameters>
|
||||||
|
<!-- parameters for the container itself -->
|
||||||
|
<Parameter name="secretKey" value="5185F447-6317-4856-B40E-573919BA0A16" />
|
||||||
|
<Parameter name="secretSalt" value="00F6E88C-A64F-410A-8FCF-9CD340E340F7" />
|
||||||
|
<Parameter name="persistSessions" value="true" />
|
||||||
|
<Parameter name="persistSessionsPath" value="./target/${target}/sessions.dat" />
|
||||||
|
<Parameter name="autoPersistOnUserChangesData" value="true" />
|
||||||
|
<Parameter name="privilegeConflictResolution" value="STRICT" />
|
||||||
|
</Parameters>
|
||||||
|
|
||||||
|
<EncryptionHandler class="ch.eitchnet.privilege.handler.DefaultEncryptionHandler">
|
||||||
|
<Parameters>
|
||||||
|
<Parameter name="hashAlgorithm" value="SHA-256" />
|
||||||
|
</Parameters>
|
||||||
|
</EncryptionHandler>
|
||||||
|
|
||||||
|
<PersistenceHandler class="ch.eitchnet.privilege.handler.XmlPersistenceHandler">
|
||||||
|
<Parameters>
|
||||||
|
<Parameter name="basePath" value="./target/${target}" />
|
||||||
|
<Parameter name="usersXmlFile" value="PrivilegeUsers.xml" />
|
||||||
|
<Parameter name="rolesXmlFile" value="PrivilegeRoles.xml" />
|
||||||
|
</Parameters>
|
||||||
|
</PersistenceHandler>
|
||||||
|
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Policies>
|
||||||
|
<Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
|
||||||
|
<Policy name="RoleAccessPrivilege" class="ch.eitchnet.privilege.policy.RoleAccessPrivilege" />
|
||||||
|
<Policy name="UserAccessPrivilege" class="ch.eitchnet.privilege.policy.UserAccessPrivilege" />
|
||||||
|
</Policies>
|
||||||
|
|
||||||
|
</Privilege>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Privilege>
|
||||||
|
|
||||||
|
<Container>
|
||||||
|
|
||||||
|
<Parameters>
|
||||||
|
<!-- parameters for the container itself -->
|
||||||
|
<Parameter name="autoPersistOnUserChangesData" value="true" />
|
||||||
|
<Parameter name="privilegeConflictResolution" value="MERGE" />
|
||||||
|
</Parameters>
|
||||||
|
|
||||||
|
<EncryptionHandler class="ch.eitchnet.privilege.handler.DefaultEncryptionHandler">
|
||||||
|
<Parameters>
|
||||||
|
<Parameter name="hashAlgorithm" value="SHA-256" />
|
||||||
|
</Parameters>
|
||||||
|
</EncryptionHandler>
|
||||||
|
|
||||||
|
<PersistenceHandler class="ch.eitchnet.privilege.handler.XmlPersistenceHandler">
|
||||||
|
<Parameters>
|
||||||
|
<Parameter name="basePath" value="./target/${target}" />
|
||||||
|
<Parameter name="usersXmlFile" value="PrivilegeUsersMerge.xml" />
|
||||||
|
<Parameter name="rolesXmlFile" value="PrivilegeRolesMerge.xml" />
|
||||||
|
</Parameters>
|
||||||
|
</PersistenceHandler>
|
||||||
|
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<Policies>
|
||||||
|
<Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
|
||||||
|
<Policy name="RoleAccessPrivilege" class="ch.eitchnet.privilege.policy.RoleAccessPrivilege" />
|
||||||
|
<Policy name="UserAccessPrivilege" class="ch.eitchnet.privilege.policy.UserAccessPrivilege" />
|
||||||
|
</Policies>
|
||||||
|
|
||||||
|
</Privilege>
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Roles>
|
||||||
|
|
||||||
|
<Role name="PrivilegeAdmin">
|
||||||
|
<Privilege name="PrivilegeAction" policy="DefaultPrivilege">
|
||||||
|
<Allow>Persist</Allow>
|
||||||
|
<Allow>Reload</Allow>
|
||||||
|
<Allow>GetPolicies</Allow>
|
||||||
|
</Privilege>
|
||||||
|
|
||||||
|
<Privilege name="PrivilegeGetRole" policy="RoleAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeAddRole" policy="RoleAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeRemoveRole" policy="RoleAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeModifyRole" policy="RoleAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
|
||||||
|
<Privilege name="PrivilegeGetUser" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeAddUser" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeRemoveUser" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeModifyUser" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeAddRoleToUser" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeRemoveRoleFromUser" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeSetUserLocale" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeSetUserState" policy="UserAccessPrivilege">
|
||||||
|
<Allow>ENABLED</Allow>
|
||||||
|
<Allow>DISABLED</Allow>
|
||||||
|
<Deny>SYSTEM</Deny>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="PrivilegeSetUserPassword" policy="UserAccessPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
<Role name="AppUser">
|
||||||
|
<Privilege name="ch.eitchnet.privilege.test.model.TestRestrictable" policy="DefaultPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
<Role name="MyRole">
|
||||||
|
<Privilege name="Foo" policy="DefaultPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
<Role name="MyRole2">
|
||||||
|
<Privilege name="Foo" policy="DefaultPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
<Role name="system_admin_privileges">
|
||||||
|
<Privilege name="ch.eitchnet.privilege.handler.SystemUserAction" policy="DefaultPrivilege">
|
||||||
|
<Allow>ch.eitchnet.privilege.test.model.TestSystemUserAction</Allow>
|
||||||
|
<Deny>ch.eitchnet.privilege.test.model.TestSystemUserActionDeny</Deny>
|
||||||
|
</Privilege>
|
||||||
|
<Privilege name="ch.eitchnet.privilege.test.model.TestSystemRestrictable" policy="DefaultPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
<Role name="restrictedRole">
|
||||||
|
<Privilege name="ch.eitchnet.privilege.handler.SystemUserAction" policy="DefaultPrivilege">
|
||||||
|
<Allow>hello</Allow>
|
||||||
|
<Deny>goodbye</Deny>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
</Roles>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Roles>
|
||||||
|
|
||||||
|
<Role name="RoleA1">
|
||||||
|
<Privilege name="Foo" policy="DefaultPrivilege">
|
||||||
|
<Allow>allow1</Allow>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
<Role name="RoleA2">
|
||||||
|
<Privilege name="Foo" policy="DefaultPrivilege">
|
||||||
|
<AllAllowed>true</AllAllowed>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
<Role name="RoleB1">
|
||||||
|
<Privilege name="Bar" policy="DefaultPrivilege">
|
||||||
|
<Allow>allow1</Allow>
|
||||||
|
<Deny>deny1</Deny>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
<Role name="RoleB2">
|
||||||
|
<Privilege name="Bar" policy="DefaultPrivilege">
|
||||||
|
<Allow>allow2</Allow>
|
||||||
|
<Deny>deny2</Deny>
|
||||||
|
</Privilege>
|
||||||
|
</Role>
|
||||||
|
|
||||||
|
</Roles>
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Users>
|
||||||
|
|
||||||
|
<User userId="1" username="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918">
|
||||||
|
<Firstname>Application</Firstname>
|
||||||
|
<Lastname>Administrator</Lastname>
|
||||||
|
<State>ENABLED</State>
|
||||||
|
<Locale>en_GB</Locale>
|
||||||
|
<Roles>
|
||||||
|
<Role>PrivilegeAdmin</Role>
|
||||||
|
<Role>AppUser</Role>
|
||||||
|
</Roles>
|
||||||
|
<Properties>
|
||||||
|
<Property name="organization" value="eitchnet.ch" />
|
||||||
|
<Property name="organizationalUnit" value="Development" />
|
||||||
|
</Properties>
|
||||||
|
</User>
|
||||||
|
|
||||||
|
<User userId="2" username="system_admin">
|
||||||
|
<Firstname>System User</Firstname>
|
||||||
|
<Lastname>Administrator</Lastname>
|
||||||
|
<State>SYSTEM</State>
|
||||||
|
<Locale>en_GB</Locale>
|
||||||
|
<Roles>
|
||||||
|
<Role>system_admin_privileges</Role>
|
||||||
|
</Roles>
|
||||||
|
</User>
|
||||||
|
|
||||||
|
<User userId="3" username="system_admin2">
|
||||||
|
<Firstname>System User</Firstname>
|
||||||
|
<Lastname>Administrator</Lastname>
|
||||||
|
<State>SYSTEM</State>
|
||||||
|
<Locale>en_GB</Locale>
|
||||||
|
<Roles>
|
||||||
|
<Role>system_admin_privileges</Role>
|
||||||
|
</Roles>
|
||||||
|
</User>
|
||||||
|
|
||||||
|
</Users>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Users>
|
||||||
|
|
||||||
|
<User userId="1" username="userA" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918">
|
||||||
|
<Firstname>System User</Firstname>
|
||||||
|
<Lastname>Administrator</Lastname>
|
||||||
|
<State>ENABLED</State>
|
||||||
|
<Locale>en_GB</Locale>
|
||||||
|
<Roles>
|
||||||
|
<Role>RoleA1</Role>
|
||||||
|
<Role>RoleA2</Role>
|
||||||
|
</Roles>
|
||||||
|
</User>
|
||||||
|
|
||||||
|
<User userId="2" username="userB" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918">
|
||||||
|
<Firstname>System User</Firstname>
|
||||||
|
<Lastname>Administrator</Lastname>
|
||||||
|
<State>ENABLED</State>
|
||||||
|
<Locale>en_GB</Locale>
|
||||||
|
<Roles>
|
||||||
|
<Role>RoleB1</Role>
|
||||||
|
<Role>RoleB2</Role>
|
||||||
|
</Roles>
|
||||||
|
</User>
|
||||||
|
|
||||||
|
</Users>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,11 @@
|
||||||
|
A list of TODOs for Privilege
|
||||||
|
============================================
|
||||||
|
|
||||||
|
- Write up a proper explanation on the idea on how Privilege, PrivilegePolicy,
|
||||||
|
Restrictable and Roles fit together to grant privileges to Users
|
||||||
|
|
||||||
|
- i18n for any messages and exceptions!
|
||||||
|
|
||||||
|
- Finish the JavaDoc
|
||||||
|
|
||||||
|
- Set up a website =)
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>ch.eitchnet</groupId>
|
||||||
|
<artifactId>ch.eitchnet.parent</artifactId>
|
||||||
|
<version>1.1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../ch.eitchnet.parent/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ch.eitchnet.privilege</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>ch.eitchnet.privilege</name>
|
||||||
|
<url>https://github.com/eitchnet/ch.eitchnet.privilege</url>
|
||||||
|
<inceptionYear>2011</inceptionYear>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<eitchnet.utils.version>1.1.0-SNAPSHOT</eitchnet.utils.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<issueManagement>
|
||||||
|
<system>Github Issues</system>
|
||||||
|
<url>https://github.com/eitchnet/ch.eitchnet.privilege/issues</url>
|
||||||
|
</issueManagement>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:git:https://github.com/eitchnet/ch.eitchnet.privilege.git</connection>
|
||||||
|
<developerConnection>scm:git:git@github.com:eitchnet/ch.eitchnet.privilege.git</developerConnection>
|
||||||
|
<url>https://github.com/eitchnet/ch.eitchnet.privilege</url>
|
||||||
|
<tag>HEAD</tag>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.eitchnet</groupId>
|
||||||
|
<artifactId>ch.eitchnet.utils</artifactId>
|
||||||
|
<version>${eitchnet.utils.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-eclipse-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-site-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<jardesc>
|
||||||
|
<jar path="/home/eitch/privilege.jar"/>
|
||||||
|
<options buildIfNeeded="true" compress="true" descriptionLocation="/Privilege/privilege.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="false" storeRefactorings="false" useSourceFolders="false"/>
|
||||||
|
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
|
||||||
|
<selectedProjects/>
|
||||||
|
<manifest generateManifest="false" manifestLocation="/Privilege/MANIFEST.MF" manifestVersion="1.0" reuseManifest="false" saveManifest="true" usesManifest="true">
|
||||||
|
<sealing sealJar="false">
|
||||||
|
<packagesToSeal/>
|
||||||
|
<packagesToUnSeal/>
|
||||||
|
</sealing>
|
||||||
|
</manifest>
|
||||||
|
<selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
|
||||||
|
<javaElement handleIdentifier="=Privilege/src"/>
|
||||||
|
<file path="/Privilege/.classpath"/>
|
||||||
|
<file path="/Privilege/.project"/>
|
||||||
|
</selectedElements>
|
||||||
|
</jardesc>
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown if access is denied during login, or if a certain privilege is not granted
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class AccessDeniedException extends PrivilegeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg
|
||||||
|
* detail on why and where access was denied
|
||||||
|
*/
|
||||||
|
public AccessDeniedException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ch.eitchnet.privilege.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown if the given credentials are invalid
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class InvalidCredentialsException extends AccessDeniedException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg
|
||||||
|
* the message to accompany the exception
|
||||||
|
*/
|
||||||
|
public InvalidCredentialsException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.base;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PrivilegeConflictResolution} defines what should be done if a {@link User} has {@link Role Roles} which
|
||||||
|
* have Privileges with conflicting names.
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public enum PrivilegeConflictResolution {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STRICT requires that a User may not have conflicting Privileges throug multiple Roles. In this case an Exception
|
||||||
|
* is thrown.
|
||||||
|
*/
|
||||||
|
STRICT {
|
||||||
|
@Override
|
||||||
|
public boolean isStrict() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MERGE defines that if conflicting privileges are encountered then a merge is to take place. A merge means that if
|
||||||
|
* all is allowed, then that wins. Otherwise any existing allow and deny lists are merged
|
||||||
|
*/
|
||||||
|
MERGE {
|
||||||
|
@Override
|
||||||
|
public boolean isStrict() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract boolean isStrict();
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main {@link RuntimeException} thrown if something goes wrong in Privilege
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* message to go with the exception
|
||||||
|
*/
|
||||||
|
public PrivilegeException(String string) {
|
||||||
|
super(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with underlying exception
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* message to go with the exception
|
||||||
|
* @param t
|
||||||
|
* throwable to wrap with this exception which is the underlying exception of this exception
|
||||||
|
*/
|
||||||
|
public PrivilegeException(String string, Throwable t) {
|
||||||
|
super(string, t);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.handler;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This default {@link EncryptionHandler} creates tokens using a {@link SecureRandom} object. Hashing is done by using
|
||||||
|
* {@link MessageDigest} and the configured algorithm which is passed in the parameters
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* Required parameters:
|
||||||
|
* <ul>
|
||||||
|
* <li> {@link XmlConstants#XML_PARAM_HASH_ALGORITHM}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class DefaultEncryptionHandler implements EncryptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The log4j logger used in this instance
|
||||||
|
*/
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DefaultEncryptionHandler.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SecureRandom} which is used to create new tokens
|
||||||
|
*/
|
||||||
|
private SecureRandom secureRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The configured hash algorithm for this instance
|
||||||
|
*/
|
||||||
|
private String hashAlgorithm;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToHash(String string) {
|
||||||
|
return convertToHash(string.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToHash(byte[] bytes) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
return StringHelper.hashAsHex(this.hashAlgorithm, bytes);
|
||||||
|
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
if (e.getCause() == null)
|
||||||
|
throw e;
|
||||||
|
if (e.getCause().getClass().equals(NoSuchAlgorithmException.class))
|
||||||
|
throw new PrivilegeException(
|
||||||
|
MessageFormat.format("Algorithm {0} was not found!", this.hashAlgorithm), e.getCause()); //$NON-NLS-1$
|
||||||
|
if (e.getCause().getClass().equals(UnsupportedEncodingException.class))
|
||||||
|
throw new PrivilegeException("Charset ASCII is not supported!", e.getCause()); //$NON-NLS-1$
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String nextToken() {
|
||||||
|
byte[] bytes = new byte[16];
|
||||||
|
this.secureRandom.nextBytes(bytes);
|
||||||
|
String randomString = new String(bytes);
|
||||||
|
return randomString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(Map<String, String> parameterMap) {
|
||||||
|
|
||||||
|
this.secureRandom = new SecureRandom();
|
||||||
|
|
||||||
|
// get hash algorithm parameters
|
||||||
|
this.hashAlgorithm = parameterMap.get(XmlConstants.XML_PARAM_HASH_ALGORITHM);
|
||||||
|
if (this.hashAlgorithm == null || this.hashAlgorithm.isEmpty()) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is invalid"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), XmlConstants.XML_PARAM_HASH_ALGORITHM);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test hash algorithm
|
||||||
|
try {
|
||||||
|
convertToHash("test"); //$NON-NLS-1$
|
||||||
|
DefaultEncryptionHandler.logger.info(MessageFormat
|
||||||
|
.format("Using hashing algorithm {0}", this.hashAlgorithm)); //$NON-NLS-1$
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is invalid because of underlying exception: {2}"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, EncryptionHandler.class.getName(), XmlConstants.XML_PARAM_HASH_ALGORITHM,
|
||||||
|
e.getLocalizedMessage());
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link EncryptionHandler} exposes API which is used to handle encrypting of strings, or returning secure tokens
|
||||||
|
* for certificates and so forth
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public interface EncryptionHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates or generates a token which can be used to identify certificates and so forth
|
||||||
|
*
|
||||||
|
* @return the secure token
|
||||||
|
*/
|
||||||
|
public String nextToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a given string, e.g. a password to a hash which is defined by the concrete implementation
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the string to convert
|
||||||
|
* @return the hash of the string after converting
|
||||||
|
*/
|
||||||
|
public String convertToHash(String string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a given byte array, e.g. a password to a hash which is defined by the concrete implementation
|
||||||
|
*
|
||||||
|
* @param bytes
|
||||||
|
* the bytes to convert
|
||||||
|
* @return the hash of the string after converting
|
||||||
|
*/
|
||||||
|
public String convertToHash(byte[] bytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the concrete {@link EncryptionHandler}. The passed parameter map contains any configuration the
|
||||||
|
* concrete {@link EncryptionHandler} might need
|
||||||
|
*
|
||||||
|
* @param parameterMap
|
||||||
|
* a map containing configuration properties
|
||||||
|
*/
|
||||||
|
public void initialize(Map<String, String> parameterMap);
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.handler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* The {@link PersistenceHandler} takes care of retrieving and persisting model objects to the underlying database. This
|
||||||
|
* database can be simple XML files, or an LDAP and so forth
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The {@link PersistenceHandler} also serves the special {@link PrivilegePolicy} objects. These policies are special
|
||||||
|
* objects which implement an algorithm to define if an action is allowed on a {@link Restrictable} by a {@link Role}
|
||||||
|
* and {@link IPrivilege}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public interface PersistenceHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all currently known {@link User}s
|
||||||
|
*
|
||||||
|
* @return all currently known {@link User}s
|
||||||
|
*/
|
||||||
|
public List<User> getAllUsers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all currently known {@link Role}s
|
||||||
|
*
|
||||||
|
* @return all currently known {@link Role}s
|
||||||
|
*/
|
||||||
|
public List<Role> getAllRoles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link User} object from the underlying database
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* the name/id of the {@link User} object to return
|
||||||
|
*
|
||||||
|
* @return the {@link User} object, or null if it was not found
|
||||||
|
*/
|
||||||
|
public User getUser(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link Role} object from the underlying database
|
||||||
|
*
|
||||||
|
* @param roleName
|
||||||
|
* the name/id of the {@link Role} object to return
|
||||||
|
*
|
||||||
|
* @return the {@link Role} object, or null if it was not found
|
||||||
|
*/
|
||||||
|
public Role getRole(String roleName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a {@link User} with the given name and returns the removed object if it existed
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* the name of the {@link User} to remove
|
||||||
|
*
|
||||||
|
* @return the {@link User} removed, or null if it did not exist
|
||||||
|
*/
|
||||||
|
public User removeUser(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a {@link Role} with the given name and returns the removed object if it existed
|
||||||
|
*
|
||||||
|
* @param roleName
|
||||||
|
* the name of the {@link Role} to remove
|
||||||
|
*
|
||||||
|
* @return the {@link Role} removed, or null if it did not exist
|
||||||
|
*/
|
||||||
|
public Role removeRole(String roleName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@link User} object to the underlying database
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* the {@link User} object to add
|
||||||
|
*/
|
||||||
|
public void addUser(User user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the existing {@link User} object in the underlying database
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* the {@link User} object to add
|
||||||
|
*/
|
||||||
|
public void replaceUser(User user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@link Role} object to the underlying database
|
||||||
|
*
|
||||||
|
* @param role
|
||||||
|
* the {@link User} object to add
|
||||||
|
*/
|
||||||
|
public void addRole(Role role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the {@link Role} object in the underlying database
|
||||||
|
*
|
||||||
|
* @param role
|
||||||
|
* the {@link User} object to add
|
||||||
|
*/
|
||||||
|
public void replaceRole(Role role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs this {@link PersistenceHandler} to persist any changes which need to be saved
|
||||||
|
*
|
||||||
|
* @return true if changes were persisted successfully, false if nothing needed to be persisted
|
||||||
|
*/
|
||||||
|
public boolean persist();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informs this {@link PersistenceHandler} to reload the data from the backend
|
||||||
|
*
|
||||||
|
* @return true if the reload was successful, false if something went wrong
|
||||||
|
*/
|
||||||
|
public boolean reload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the concrete {@link PersistenceHandler}. The passed parameter map contains any configuration the
|
||||||
|
* concrete {@link PersistenceHandler} might need
|
||||||
|
*
|
||||||
|
* @param parameterMap
|
||||||
|
* a map containing configuration properties
|
||||||
|
*/
|
||||||
|
public void initialize(Map<String, String> parameterMap);
|
||||||
|
}
|
|
@ -0,0 +1,689 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.handler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeConflictResolution;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeRep;
|
||||||
|
import ch.eitchnet.privilege.model.RoleRep;
|
||||||
|
import ch.eitchnet.privilege.model.UserRep;
|
||||||
|
import ch.eitchnet.privilege.model.UserState;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link PrivilegeHandler} is the centrally exposed API for accessing the privilege library. It exposes all needed
|
||||||
|
* methods to access Privilege data model objects, modify them and validate if users or roles have privileges to perform
|
||||||
|
* an action
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public interface PrivilegeHandler {
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeAction" which is used for privileges which are not further categorized e.g. s
|
||||||
|
* {@link #PRIVILEGE_ACTION_PERSIST} and {@link #PRIVILEGE_ACTION_GET_POLICIES}
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION = "PrivilegeAction";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For Privilege "PrivilegeAction" value required to be able to persist changes if not exempted by auto persist or
|
||||||
|
* <code>allAllowed</code>
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION_PERSIST = "Persist";
|
||||||
|
/**
|
||||||
|
* For Privilege "PrivilegeAction" value required to be able to persist session if not exempted by
|
||||||
|
* <code>allAllowed</code>
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION_PERSIST_SESSIONS = "PersistSessions";
|
||||||
|
/**
|
||||||
|
* For Privilege "PrivilegeAction" value required to be able to reload changes if not exempted by
|
||||||
|
* <code>allAllowed</code>
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION_RELOAD = "Reload";
|
||||||
|
/**
|
||||||
|
* For Privilege "PrivilegeAction" value required to get currently configured policies if not
|
||||||
|
* <code>allAllowed</code>
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION_GET_POLICIES = "GetPolicies";
|
||||||
|
/**
|
||||||
|
* For Privilege "PrivilegeAction" value required to get a certificate if not <code>allAllowed</code>
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION_GET_CERTIFICATE = "GetCertificate";
|
||||||
|
/**
|
||||||
|
* For Privilege "PrivilegeAction" value required to get all certificates if not <code>allAllowed</code>
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ACTION_GET_CERTIFICATES = "GetCertificates";
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeGetRole" which is used to validate that a user can get a specific role
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_GET_ROLE = "PrivilegeGetRole";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeAddRole" which is used to validate that a user can add a specific role
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ADD_ROLE = "PrivilegeAddRole";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeRemoveRole" which is used to validate that a user can remove a specific role
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_REMOVE_ROLE = "PrivilegeRemoveRole";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeModifyRole" which is used to validate that a user can modify a specific role. <b>Note:</b>
|
||||||
|
* This includes modifying of the privileges on the role
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_MODIFY_ROLE = "PrivilegeModifyRole";
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeGetUser" which is used to validate that a user can get a specific user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_GET_USER = "PrivilegeGetUser";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeAddUser" which is used to validate that a user can add a specific user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ADD_USER = "PrivilegeAddUser";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeRemoveUser" which is used to validate that a user can remove a specific user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_REMOVE_USER = "PrivilegeRemoveUser";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeModifyUser" which is used to validate that a user can modify a specific user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_MODIFY_USER = "PrivilegeModifyUser";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeAddRoleToUser" which is used to validate that a user can add a specific role to a specific
|
||||||
|
* user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_ADD_ROLE_TO_USER = "PrivilegeAddRoleToUser";
|
||||||
|
/**
|
||||||
|
* Privilege "PrivilegeRemoveRoleFromUser" which is used to validate that a user can remove a specific role from a
|
||||||
|
* specific user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_REMOVE_ROLE_FROM_USER = "PrivilegeRemoveRoleFromUser";
|
||||||
|
/**
|
||||||
|
* Privilege "PRIVILEGE_SET_USER_LOCALE" which is used to validate that a user can set the locale of a user, or
|
||||||
|
* their own
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_SET_USER_LOCALE = "PrivilegeSetUserLocale";
|
||||||
|
/**
|
||||||
|
* Privilege "PRIVILEGE_SET_USER_STATE" which is used to validate that a user can set the state of a user
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_SET_USER_STATE = "PrivilegeSetUserState";
|
||||||
|
/**
|
||||||
|
* Privilege "PRIVILEGE_SET_USER_PASSWORD" which is used to validate that a user can set the password of a user, or
|
||||||
|
* their own
|
||||||
|
*/
|
||||||
|
public static final String PRIVILEGE_SET_USER_PASSWORD = "PrivilegeSetUserPassword";
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameter to define a secret_key
|
||||||
|
*/
|
||||||
|
public static final String PARAM_SECRET_KEY = "secretKey"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameter to define a secret salt
|
||||||
|
*/
|
||||||
|
public static final String PARAM_SECRET_SALT = "secretSalt"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameter to define automatic persisting on password change
|
||||||
|
*/
|
||||||
|
public static final String PARAM_AUTO_PERSIST_ON_USER_CHANGES_DATA = "autoPersistOnUserChangesData"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameter to define if sessions should be persisted
|
||||||
|
*/
|
||||||
|
public static final String PARAM_PERSIST_SESSIONS = "persistSessions"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameter to define where sessions are to be persisted
|
||||||
|
*/
|
||||||
|
public static final String PARAM_PERSIST_SESSIONS_PATH = "persistSessionsPath"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration parameter to define {@link PrivilegeConflictResolution}
|
||||||
|
*/
|
||||||
|
public static final String PARAM_PRIVILEGE_CONFLICT_RESOLUTION = "privilegeConflictResolution";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link UserRep} for the given username
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the name of the {@link UserRep} to return
|
||||||
|
*
|
||||||
|
* @return the {@link UserRep} for the given username, or null if it was not found
|
||||||
|
*/
|
||||||
|
public UserRep getUser(Certificate certificate, String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link RoleRep} for the given roleName
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param roleName
|
||||||
|
* the name of the {@link RoleRep} to return
|
||||||
|
*
|
||||||
|
* @return the {@link RoleRep} for the given roleName, or null if it was not found
|
||||||
|
*/
|
||||||
|
public RoleRep getRole(Certificate certificate, String roleName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of {@link PrivilegePolicy} definitions
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return the map of {@link PrivilegePolicy} definitions
|
||||||
|
*/
|
||||||
|
public Map<String, String> getPolicyDefs(Certificate certificate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of {@link Certificate Certificates}
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return the list of {@link Certificate Certificates}
|
||||||
|
*/
|
||||||
|
public List<Certificate> getCertificates(Certificate certificate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all {@link RoleRep RoleReps}
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return the list of {@link RoleRep RoleReps}
|
||||||
|
*/
|
||||||
|
public List<RoleRep> getRoles(Certificate certificate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all {@link UserRep UserReps}
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return the list of {@link UserRep UserReps}
|
||||||
|
*/
|
||||||
|
public List<UserRep> getUsers(Certificate certificate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to query {@link UserRep} which meet the criteria set in the given {@link UserRep}. Null fields mean the
|
||||||
|
* fields are irrelevant.
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param selectorRep
|
||||||
|
* the {@link UserRep} to use as criteria selection
|
||||||
|
*
|
||||||
|
* @return a list of {@link UserRep}s which fit the given criteria
|
||||||
|
*/
|
||||||
|
public List<UserRep> queryUsers(Certificate certificate, UserRep selectorRep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the user with the given username
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the username of the user to remove
|
||||||
|
*
|
||||||
|
* @return the {@link UserRep} of the user removed, or null if the user did not exist
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public UserRep removeUser(Certificate certificate, String username)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the role with the given roleName from the user with the given username
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the username of the user from which the role is to be removed
|
||||||
|
* @param roleName
|
||||||
|
* the roleName of the role to remove from the user
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public UserRep removeRoleFromUser(Certificate certificate, String username, String roleName)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the role with the given roleName
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param roleName
|
||||||
|
* the roleName of the role to remove
|
||||||
|
*
|
||||||
|
* @return the {@link RoleRep} of the role removed, or null if the role did not exist
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or the role is still in use by a user
|
||||||
|
*/
|
||||||
|
public RoleRep removeRole(Certificate certificate, String roleName)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the privilege with the given privilegeName from the role with the given roleName
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param roleName
|
||||||
|
* the roleName of the role from which the privilege is to be removed
|
||||||
|
* @param privilegeName
|
||||||
|
* the privilegeName of the privilege to remove from the role
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public RoleRep removePrivilegeFromRole(Certificate certificate, String roleName, String privilegeName)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Adds a new user with the information from this {@link UserRep}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
|
||||||
|
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(byte[])}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param userRep
|
||||||
|
* the {@link UserRep} containing the information to create the new {@link User}
|
||||||
|
* @param password
|
||||||
|
* the password of the new user. If the password is null, then this is accepted but the user can not
|
||||||
|
* login, otherwise the password must be validated against
|
||||||
|
* {@link PrivilegeHandler#validatePassword(byte[])}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or the user already exists
|
||||||
|
*/
|
||||||
|
public UserRep addUser(Certificate certificate, UserRep userRep, byte[] password)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Updates the fields for the user with the given user. All fields on the given {@link UserRep} which are non-null
|
||||||
|
* will be updated on the existing user. The username on the given {@link UserRep} must be set and correspond to an
|
||||||
|
* existing user.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* The following fields are considered updateable:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link UserRep#getFirstname()}</li>
|
||||||
|
* <li>{@link UserRep#getLastname()}</li>
|
||||||
|
* <li>{@link UserRep#getLocale()}</li>
|
||||||
|
* <li>{@link UserRep#getProperties()} - the existing properties will be replaced with the given properties</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Any other fields will be ignored
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param userRep
|
||||||
|
* the {@link UserRep} with the fields set to their new values
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or if the user does not exist
|
||||||
|
*/
|
||||||
|
public UserRep updateUser(Certificate certificate, UserRep userRep)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Replaces the existing user with the information from this {@link UserRep} if the user already exists
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If the password given is null, then the user is created, but can not not login! Otherwise the password must meet
|
||||||
|
* the requirements of the implementation under {@link PrivilegeHandler#validatePassword(byte[])}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param userRep
|
||||||
|
* the {@link UserRep} containing the information to replace the existing {@link User}
|
||||||
|
* @param password
|
||||||
|
* the password of the new user. If the password is null, then this is accepted but the user can not
|
||||||
|
* login, otherwise the password must be validated against
|
||||||
|
* {@link PrivilegeHandler#validatePassword(byte[])}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or if the user does not exist
|
||||||
|
*/
|
||||||
|
public UserRep replaceUser(Certificate certificate, UserRep userRep, byte[] password)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new role with the information from this {@link RoleRep}
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param roleRep
|
||||||
|
* the {@link RoleRep} containing the information to create the new {@link Role}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or if the role already exists
|
||||||
|
*/
|
||||||
|
public RoleRep addRole(Certificate certificate, RoleRep roleRep) throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the existing role with the information from this {@link RoleRep}
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param roleRep
|
||||||
|
* the {@link RoleRep} containing the information to replace the existing {@link Role}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or if the role does not exist
|
||||||
|
*/
|
||||||
|
public RoleRep replaceRole(Certificate certificate, RoleRep roleRep)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the role with the given roleName to the {@link User} with the given username
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the username of the {@link User} to which the role should be added
|
||||||
|
* @param roleName
|
||||||
|
* the roleName of the {@link Role} which should be added to the {@link User}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or if the role does not exist
|
||||||
|
*/
|
||||||
|
public UserRep addRoleToUser(Certificate certificate, String username, String roleName)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the {@link PrivilegeRep} to the {@link Role} with the given roleName or replaces it, if it already exists
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param roleName
|
||||||
|
* the roleName of the {@link Role} to which the privilege should be added
|
||||||
|
* @param privilegeRep
|
||||||
|
* the representation of the {@link IPrivilege} which should be added or replaced on the {@link Role}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate or the role does not exist
|
||||||
|
*/
|
||||||
|
public RoleRep addOrReplacePrivilegeOnRole(Certificate certificate, String roleName, PrivilegeRep privilegeRep)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Changes the password for the {@link User} with the given username. If the password is null, then the {@link User}
|
||||||
|
* can not login anymore. Otherwise the password must meet the requirements of the implementation under
|
||||||
|
* {@link PrivilegeHandler#validatePassword(byte[])}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* It should be possible for a user to change their own password
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the username of the {@link User} for which the password is to be changed
|
||||||
|
* @param password
|
||||||
|
* the new password for this user. If the password is null, then the {@link User} can not login anymore.
|
||||||
|
* Otherwise the password must meet the requirements of the implementation under
|
||||||
|
* {@link PrivilegeHandler#validatePassword(byte[])}
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public void setUserPassword(Certificate certificate, String username, byte[] password)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the {@link UserState} of the user
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the username of the {@link User} for which the {@link UserState} is to be changed
|
||||||
|
* @param state
|
||||||
|
* the new state for the user
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public UserRep setUserState(Certificate certificate, String username, UserState state)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the {@link Locale} of the user
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
* @param username
|
||||||
|
* the username of the {@link User} for which the {@link Locale} is to be changed
|
||||||
|
* @param locale
|
||||||
|
* the new {@link Locale} for the user
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user for this certificate may not perform the action
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public UserRep setUserLocale(Certificate certificate, String username, Locale locale)
|
||||||
|
throws AccessDeniedException, PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates a user by validating that a {@link User} for the given username and password exist and then returns
|
||||||
|
* a {@link Certificate} with which this user may then perform actions
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* the username of the {@link User} which is registered in the {@link PersistenceHandler}
|
||||||
|
* @param password
|
||||||
|
* the password with which this user is to be authenticated. Null passwords are not accepted and they
|
||||||
|
* must meet the requirements of the {@link #validatePassword(byte[])}-method
|
||||||
|
*
|
||||||
|
* @return a {@link Certificate} with which this user may then perform actions
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user credentials are not valid
|
||||||
|
*/
|
||||||
|
public Certificate authenticate(String username, byte[] password) throws AccessDeniedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates the session for the given {@link Certificate}, effectively logging out the user who was authenticated
|
||||||
|
* with the credentials associated to the given {@link Certificate}
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} for which the session is to be invalidated
|
||||||
|
* @return true if the session was still valid and is now invalidated, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean invalidateSession(Certificate certificate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given {@link Certificate} is valid. This means that the certificate is for a valid session and that
|
||||||
|
* the user exists for the certificate. This method checks if the {@link Certificate} has been tampered with
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} to check
|
||||||
|
*
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is anything wrong with this certificate
|
||||||
|
*/
|
||||||
|
public void isCertificateValid(Certificate certificate) throws PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the given password belongs to the given {@link Certificate}. If it doesn't, then a
|
||||||
|
* {@link PrivilegeException} is thrown
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the certificate for which to check the password
|
||||||
|
* @param password
|
||||||
|
* the password to check against the user from the certificate
|
||||||
|
*
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if the certificate is invalid or the password does not match
|
||||||
|
*/
|
||||||
|
public void checkPassword(Certificate certificate, byte[] password) throws PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an
|
||||||
|
* encapsulated state of a user's privileges so that for the duration of a user's call, the user can perform their
|
||||||
|
* actions and do not need to access the {@link PrivilegeHandler} anymore
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* a valid {@link Certificate} for which a {@link PrivilegeContext} is to be returned
|
||||||
|
* @return the {@link PrivilegeContext} for the given {@link Certificate}
|
||||||
|
*
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is a configuration error or the {@link Certificate} is invalid
|
||||||
|
*/
|
||||||
|
public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that the given password meets certain requirements. What these requirements are is a decision made by
|
||||||
|
* the concrete implementation
|
||||||
|
*
|
||||||
|
* @param password
|
||||||
|
* the password to be validated to meet certain requirements
|
||||||
|
*
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if the password does not implement the requirement of the concrete implementation
|
||||||
|
*/
|
||||||
|
public void validatePassword(byte[] password) throws PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Informs this {@link PersistenceHandler} to reload the data from the backend
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <b>Note:</b> It depends on the underlying {@link PersistenceHandler} implementation if data really is read
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return true if the reload was successful, false if something went wrong
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the users of the given certificate does not have the privilege to perform this action
|
||||||
|
*/
|
||||||
|
public boolean reload(Certificate certificate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists any changes to the privilege data model. Changes are thus not persisted immediately, but must be
|
||||||
|
* actively performed
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return true if changes were persisted, false if no changes were persisted
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the users of the given certificate does not have the privilege to perform this action
|
||||||
|
*/
|
||||||
|
public boolean persist(Certificate certificate) throws AccessDeniedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists all currently active sessions
|
||||||
|
*
|
||||||
|
* @param certificate
|
||||||
|
* the {@link Certificate} of the user which has the privilege to perform this action
|
||||||
|
*
|
||||||
|
* @return true if changes were persisted, false if not (i.e. not enabled)
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the users of the given certificate does not have the privilege to perform this action
|
||||||
|
*/
|
||||||
|
public boolean persistSessions(Certificate certificate) throws AccessDeniedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special method to perform work as a System user, meaning the given systemUsername corresponds to an account which
|
||||||
|
* has the state {@link UserState#SYSTEM} and this user must have privilege to perform the concrete implementation
|
||||||
|
* of the given {@link SystemUserAction} instance
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param systemUsername
|
||||||
|
* the username of the system user to perform the action as
|
||||||
|
* @param action
|
||||||
|
* the action to be performed as the system user
|
||||||
|
*
|
||||||
|
* @return the action
|
||||||
|
*
|
||||||
|
* @throws PrivilegeException
|
||||||
|
*/
|
||||||
|
public <T extends SystemUserAction> T runAsSystem(String systemUsername, T action) throws PrivilegeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link EncryptionHandler} instance
|
||||||
|
*
|
||||||
|
* @return the {@link EncryptionHandler} instance
|
||||||
|
*/
|
||||||
|
public EncryptionHandler getEncryptionHandler() throws PrivilegeException;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.handler;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With this interface system actions, which are to be performed in an automated fashion, i.e. by cron jobs, can be
|
||||||
|
* implemented and then the authorized execution can be delegated to
|
||||||
|
* {@link PrivilegeHandler#runAsSystem(String, SystemUserAction)}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public abstract class SystemUserAction implements Restrictable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrivilegeName() {
|
||||||
|
return SystemUserAction.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrivilegeValue() {
|
||||||
|
return this.getClass().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be called by the {@link PrivilegeHandler} when an authorized {@link Certificate} has been
|
||||||
|
* generated to allow this action to properly validate its execution
|
||||||
|
*
|
||||||
|
* TODO: I'm not really happy with this... we might want to pass the certificate and then force the action to
|
||||||
|
* validate it to get the {@link PrivilegeContext} - we don't want the {@link PrivilegeContext} to live forever...
|
||||||
|
*
|
||||||
|
* @param privilegeContext
|
||||||
|
* the {@link PrivilegeContext} which was generated for a valid system user
|
||||||
|
*/
|
||||||
|
public abstract void execute(PrivilegeContext privilegeContext);
|
||||||
|
}
|
|
@ -0,0 +1,314 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.handler;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeRolesDomWriter;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeRolesSaxReader;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeUsersDomWriter;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeUsersSaxReader;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link PersistenceHandler} implementation which reads the configuration from XML files. These configuration is passed
|
||||||
|
* in {@link #initialize(Map)}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class XmlPersistenceHandler implements PersistenceHandler {
|
||||||
|
|
||||||
|
protected static final Logger logger = LoggerFactory.getLogger(XmlPersistenceHandler.class);
|
||||||
|
|
||||||
|
private Map<String, User> userMap;
|
||||||
|
private Map<String, Role> roleMap;
|
||||||
|
|
||||||
|
private boolean userMapDirty;
|
||||||
|
private boolean roleMapDirty;
|
||||||
|
|
||||||
|
private Map<String, String> parameterMap;
|
||||||
|
|
||||||
|
private long usersFileDate;
|
||||||
|
private long rolesFileDate;
|
||||||
|
private File usersPath;
|
||||||
|
private File rolesPath;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<User> getAllUsers() {
|
||||||
|
synchronized (this.userMap) {
|
||||||
|
return new LinkedList<>(this.userMap.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Role> getAllRoles() {
|
||||||
|
synchronized (this.roleMap) {
|
||||||
|
return new LinkedList<>(this.roleMap.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUser(String username) {
|
||||||
|
return this.userMap.get(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Role getRole(String roleName) {
|
||||||
|
return this.roleMap.get(roleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User removeUser(String username) {
|
||||||
|
User user = this.userMap.remove(username);
|
||||||
|
this.userMapDirty = user != null;
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Role removeRole(String roleName) {
|
||||||
|
Role role = this.roleMap.remove(roleName);
|
||||||
|
this.roleMapDirty = role != null;
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addUser(User user) {
|
||||||
|
if (this.userMap.containsKey(user.getUsername()))
|
||||||
|
throw new IllegalStateException(MessageFormat.format("The user {0} already exists!", user.getUsername()));
|
||||||
|
this.userMap.put(user.getUsername(), user);
|
||||||
|
this.userMapDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceUser(User user) {
|
||||||
|
if (!this.userMap.containsKey(user.getUsername()))
|
||||||
|
throw new IllegalStateException(MessageFormat
|
||||||
|
.format("The user {0} can not be replaced as it does not exiset!", user.getUsername()));
|
||||||
|
this.userMap.put(user.getUsername(), user);
|
||||||
|
this.userMapDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addRole(Role role) {
|
||||||
|
if (this.roleMap.containsKey(role.getName()))
|
||||||
|
throw new IllegalStateException(MessageFormat.format("The role {0} already exists!", role.getName()));
|
||||||
|
this.roleMap.put(role.getName(), role);
|
||||||
|
this.roleMapDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceRole(Role role) {
|
||||||
|
if (!this.roleMap.containsKey(role.getName()))
|
||||||
|
throw new IllegalStateException(
|
||||||
|
MessageFormat.format("The role {0} can not be replaced as it does not exist!", role.getName()));
|
||||||
|
this.roleMap.put(role.getName(), role);
|
||||||
|
this.roleMapDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this {@link XmlPersistenceHandler} by reading the following parameters:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link XmlConstants#XML_PARAM_BASE_PATH}</li>
|
||||||
|
* <li>{@link XmlConstants#XML_PARAM_MODEL_FILE}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initialize(Map<String, String> paramsMap) {
|
||||||
|
|
||||||
|
// copy parameter map
|
||||||
|
this.parameterMap = Collections.unmodifiableMap(new HashMap<>(paramsMap));
|
||||||
|
|
||||||
|
// get and validate base bath
|
||||||
|
String basePath = this.parameterMap.get(XmlConstants.XML_PARAM_BASE_PATH);
|
||||||
|
File basePathF = new File(basePath);
|
||||||
|
if (!basePathF.exists() && !basePathF.isDirectory()) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} does not point to a valid path at {2}"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_BASE_PATH,
|
||||||
|
basePathF.getAbsolutePath());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get users file name
|
||||||
|
String usersFileName = this.parameterMap.get(XmlConstants.XML_PARAM_USERS_FILE);
|
||||||
|
if (StringHelper.isEmpty(usersFileName)) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is not valid as it is empty!"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_USERS_FILE);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get roles file name
|
||||||
|
String rolesFileName = this.parameterMap.get(XmlConstants.XML_PARAM_ROLES_FILE);
|
||||||
|
if (StringHelper.isEmpty(rolesFileName)) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is not valid as it is empty!"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_ROLES_FILE);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate users file exists
|
||||||
|
String usersPathS = basePath + "/" + usersFileName; //$NON-NLS-1$
|
||||||
|
File usersPath = new File(usersPathS);
|
||||||
|
if (!usersPath.exists()) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is invalid as users file does not exist at path {2}"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_USERS_FILE,
|
||||||
|
usersPath.getAbsolutePath());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate roles file exists
|
||||||
|
String rolesPathS = basePath + "/" + rolesFileName; //$NON-NLS-1$
|
||||||
|
File rolesPath = new File(rolesPathS);
|
||||||
|
if (!rolesPath.exists()) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is invalid as roles file does not exist at path {2}"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_ROLES_FILE,
|
||||||
|
rolesPath.getAbsolutePath());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// save path to model
|
||||||
|
this.usersPath = usersPath;
|
||||||
|
this.rolesPath = rolesPath;
|
||||||
|
|
||||||
|
if (reload())
|
||||||
|
logger.info("Privilege Data loaded."); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the XML configuration files which contain the model. Which configuration files are parsed was defined in
|
||||||
|
* the while calling {@link #initialize(Map)}
|
||||||
|
*
|
||||||
|
* @see #initialize(Map)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean reload() {
|
||||||
|
|
||||||
|
this.roleMap = Collections.synchronizedMap(new HashMap<String, Role>());
|
||||||
|
this.userMap = Collections.synchronizedMap(new HashMap<String, User>());
|
||||||
|
|
||||||
|
// parse models xml file to XML document
|
||||||
|
PrivilegeUsersSaxReader usersXmlHandler = new PrivilegeUsersSaxReader();
|
||||||
|
XmlHelper.parseDocument(this.usersPath, usersXmlHandler);
|
||||||
|
|
||||||
|
PrivilegeRolesSaxReader rolesXmlHandler = new PrivilegeRolesSaxReader();
|
||||||
|
XmlHelper.parseDocument(this.rolesPath, rolesXmlHandler);
|
||||||
|
|
||||||
|
this.usersFileDate = this.usersPath.lastModified();
|
||||||
|
this.rolesFileDate = this.rolesPath.lastModified();
|
||||||
|
|
||||||
|
// ROLES
|
||||||
|
List<Role> roles = rolesXmlHandler.getRoles();
|
||||||
|
for (Role role : roles) {
|
||||||
|
this.roleMap.put(role.getName(), role);
|
||||||
|
}
|
||||||
|
|
||||||
|
// USERS
|
||||||
|
List<User> users = usersXmlHandler.getUsers();
|
||||||
|
for (User user : users) {
|
||||||
|
this.userMap.put(user.getUsername(), user);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.userMapDirty = false;
|
||||||
|
this.roleMapDirty = false;
|
||||||
|
|
||||||
|
logger.info(MessageFormat.format("Read {0} Users", this.userMap.size())); //$NON-NLS-1$
|
||||||
|
logger.info(MessageFormat.format("Read {0} Roles", this.roleMap.size())); //$NON-NLS-1$
|
||||||
|
|
||||||
|
// validate referenced roles exist
|
||||||
|
for (User user : users) {
|
||||||
|
for (String roleName : user.getRoles()) {
|
||||||
|
|
||||||
|
// validate that role exists
|
||||||
|
if (getRole(roleName) == null) {
|
||||||
|
String msg = "Role {0} does not exist referenced by user {1}";
|
||||||
|
msg = MessageFormat.format(msg, roleName, user.getUsername());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the model to the XML files. Where the files are written to was defined in the {@link #initialize(Map)}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean persist() {
|
||||||
|
|
||||||
|
// get users file name
|
||||||
|
String usersFileName = this.parameterMap.get(XmlConstants.XML_PARAM_USERS_FILE);
|
||||||
|
if (usersFileName == null || usersFileName.isEmpty()) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is invalid"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_USERS_FILE);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get roles file name
|
||||||
|
String rolesFileName = this.parameterMap.get(XmlConstants.XML_PARAM_ROLES_FILE);
|
||||||
|
if (rolesFileName == null || rolesFileName.isEmpty()) {
|
||||||
|
String msg = "[{0}] Defined parameter {1} is invalid"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, PersistenceHandler.class.getName(), XmlConstants.XML_PARAM_ROLES_FILE);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean saved = false;
|
||||||
|
|
||||||
|
// get users file
|
||||||
|
boolean usersFileUnchanged = this.usersPath.exists() && this.usersPath.lastModified() == this.usersFileDate;
|
||||||
|
if (usersFileUnchanged && !this.userMapDirty) {
|
||||||
|
logger.warn("Not persisting of users as current file is unchanged and users data is not dirty"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// delegate writing
|
||||||
|
PrivilegeUsersDomWriter modelWriter = new PrivilegeUsersDomWriter(getAllUsers(), this.usersPath);
|
||||||
|
modelWriter.write();
|
||||||
|
|
||||||
|
this.userMapDirty = false;
|
||||||
|
saved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get roles file
|
||||||
|
boolean rolesFileUnchanged = this.rolesPath.exists() && this.rolesPath.lastModified() == this.rolesFileDate;
|
||||||
|
if (rolesFileUnchanged && !this.roleMapDirty) {
|
||||||
|
logger.warn("Not persisting of roles as current file is unchanged and roles data is not dirty"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// delegate writing
|
||||||
|
PrivilegeRolesDomWriter modelWriter = new PrivilegeRolesDomWriter(getAllRoles(), this.rolesPath);
|
||||||
|
modelWriter.write();
|
||||||
|
|
||||||
|
this.roleMapDirty = false;
|
||||||
|
saved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset dirty states
|
||||||
|
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.helper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeConfigDomWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This class is a simple application which can be used to bootstrap a new configuration for the
|
||||||
|
* {@link PrivilegeHandler}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Simple execute the application and it will ask a few questions and then write a new set of configuration files which
|
||||||
|
* can be used to run the {@link PrivilegeHandler}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b>This class is not yet implemented!
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class BootstrapConfigurationHelper {
|
||||||
|
|
||||||
|
// private static final Logger logger = Loggerdoc.getLogger(BootstrapConfigurationHelper.class);
|
||||||
|
|
||||||
|
private static String path;
|
||||||
|
|
||||||
|
private static String defaultPrivilegeContainerXmlFile = "Privilege.xml";
|
||||||
|
|
||||||
|
//private static String basePath = "";
|
||||||
|
//private static String modelFileName = "PrivilegeUsers.xml";
|
||||||
|
//private static String hashAlgorithm = "SHA-256";
|
||||||
|
|
||||||
|
private static String defaultPersistenceHandler = "ch.eitchnet.privilege.handler.DefaultPersistenceHandler";
|
||||||
|
private static String defaultEncryptionHandler = "ch.eitchnet.privilege.handler.DefaultEncryptionHandler";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
* the args from the command line
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
// get current directory
|
||||||
|
BootstrapConfigurationHelper.path = System.getProperty("user.dir") + "/newConfig";
|
||||||
|
|
||||||
|
// TODO ask user where to save configuration, default is pwd/newConfig/....
|
||||||
|
|
||||||
|
// see if path already exists
|
||||||
|
File pathF = new File(BootstrapConfigurationHelper.path);
|
||||||
|
if (pathF.exists()) {
|
||||||
|
throw new RuntimeException("Path already exists: " + pathF.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pathF.mkdirs()) {
|
||||||
|
throw new RuntimeException("Could not create path " + pathF.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
Map<String, String> encryptionHandlerParameterMap = new HashMap<>();
|
||||||
|
Map<String, String> persistenceHandlerParameterMap = new HashMap<>();
|
||||||
|
|
||||||
|
// TODO ask other questions...
|
||||||
|
parameterMap.put("autoPersistOnPasswordChange", "true");
|
||||||
|
encryptionHandlerParameterMap.put("hashAlgorithm", "SHA-256");
|
||||||
|
persistenceHandlerParameterMap.put("basePath", "./target/test");
|
||||||
|
persistenceHandlerParameterMap.put("modelXmlFile", "PrivilegeModel.xml");
|
||||||
|
|
||||||
|
PrivilegeContainerModel containerModel = new PrivilegeContainerModel();
|
||||||
|
containerModel.setParameterMap(parameterMap);
|
||||||
|
containerModel.setEncryptionHandlerClassName(defaultEncryptionHandler);
|
||||||
|
containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap);
|
||||||
|
containerModel.setPersistenceHandlerClassName(defaultPersistenceHandler);
|
||||||
|
containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap);
|
||||||
|
|
||||||
|
containerModel.addPolicy("DefaultPrivilege", "ch.eitchnet.privilege.policy.DefaultPrivilege");
|
||||||
|
|
||||||
|
// now perform work:
|
||||||
|
File configFile = new File(BootstrapConfigurationHelper.path + "/"
|
||||||
|
+ BootstrapConfigurationHelper.defaultPrivilegeContainerXmlFile);
|
||||||
|
PrivilegeConfigDomWriter configSaxWriter = new PrivilegeConfigDomWriter(containerModel, configFile);
|
||||||
|
configSaxWriter.write();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.helper;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPasswordField;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple Swing UI to create passwords
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class PasswordCreaterUI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches the UI
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* not used
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||||
|
|
||||||
|
JFrame frame = new JFrame();
|
||||||
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
frame.setTitle("Password creator");
|
||||||
|
frame.setLayout(new GridLayout(4, 2));
|
||||||
|
|
||||||
|
JLabel digest = new JLabel("Digest:", SwingConstants.RIGHT);
|
||||||
|
JLabel password = new JLabel("Password:", SwingConstants.RIGHT);
|
||||||
|
JLabel hash = new JLabel("Hash:", SwingConstants.RIGHT);
|
||||||
|
|
||||||
|
String[] digests = new String[] { "MD2", "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512" };
|
||||||
|
final JComboBox<String> digestCombo = new JComboBox<>(digests);
|
||||||
|
digestCombo.setSelectedIndex(3);
|
||||||
|
final JPasswordField passwordField = new JPasswordField();
|
||||||
|
final JTextField hashField = new JTextField(150);
|
||||||
|
|
||||||
|
JButton digestBtn = new JButton("Digest");
|
||||||
|
|
||||||
|
passwordField.addKeyListener(new KeyListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
hashField.setText("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
digestBtn.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String digest = (String) digestCombo.getSelectedItem();
|
||||||
|
char[] passwordChar = passwordField.getPassword();
|
||||||
|
String password = new String(passwordChar);
|
||||||
|
String hash = StringHelper.hashAsHex(digest, password);
|
||||||
|
hashField.setText(hash);
|
||||||
|
} catch (Exception e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
hashField.setText("Failed: " + e1.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.add(digest);
|
||||||
|
frame.add(digestCombo);
|
||||||
|
frame.add(password);
|
||||||
|
frame.add(passwordField);
|
||||||
|
frame.add(hash);
|
||||||
|
frame.add(hashField);
|
||||||
|
frame.add(new JLabel());
|
||||||
|
frame.add(digestBtn);
|
||||||
|
|
||||||
|
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
int width = 500;
|
||||||
|
int height = 160;
|
||||||
|
frame.setSize(width, height);
|
||||||
|
frame.setLocation(screenSize.width / 2 - width, screenSize.height / 2 - height);
|
||||||
|
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.helper;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Simple main class which can be used to create a hash from a password which the user must type in at the command line
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* TODO: Note: currently the password input is echoed which is a security risk
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PasswordCreator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
* the args from the command line, NOT USED
|
||||||
|
* @throws Exception
|
||||||
|
* thrown if anything goes wrong
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
|
||||||
|
|
||||||
|
String hashAlgorithm = null;
|
||||||
|
while (hashAlgorithm == null) {
|
||||||
|
System.out.print("Hash Algorithm [SHA-256]: ");
|
||||||
|
String readLine = r.readLine().trim();
|
||||||
|
|
||||||
|
if (readLine.isEmpty()) {
|
||||||
|
hashAlgorithm = "SHA-256";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
try {
|
||||||
|
MessageDigest.getInstance(readLine);
|
||||||
|
hashAlgorithm = readLine;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getLocalizedMessage());
|
||||||
|
hashAlgorithm = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.print("Password: ");
|
||||||
|
String password = r.readLine().trim();
|
||||||
|
System.out.print("Hash is: " + StringHelper.hashAsHex(hashAlgorithm, password));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.helper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.DefaultPrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.handler.EncryptionHandler;
|
||||||
|
import ch.eitchnet.privilege.handler.PersistenceHandler;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeConfigSaxReader;
|
||||||
|
import ch.eitchnet.utils.helper.ClassHelper;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the initializing of the {@link PrivilegeHandler} by loading an XML file containing the
|
||||||
|
* configuration
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeInitializationHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the {@link DefaultPrivilegeHandler} from the configuration file
|
||||||
|
*
|
||||||
|
* @param privilegeXmlFile
|
||||||
|
* a {@link File} reference to the XML file containing the configuration for Privilege
|
||||||
|
*
|
||||||
|
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
|
||||||
|
* {@link PersistenceHandler} are set and initialized as well
|
||||||
|
*/
|
||||||
|
public static PrivilegeHandler initializeFromXml(File privilegeXmlFile) {
|
||||||
|
|
||||||
|
// make sure file exists
|
||||||
|
if (!privilegeXmlFile.exists()) {
|
||||||
|
String msg = "Privilege file does not exist at path {0}"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeXmlFile.getAbsolutePath());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delegate using input stream
|
||||||
|
try (FileInputStream fin = new FileInputStream(privilegeXmlFile)) {
|
||||||
|
return initializeFromXml(fin);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = "Failed to load configuration from {0}"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeXmlFile.getAbsolutePath());
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the {@link PrivilegeHandler} by loading from the given input stream. This stream must be a valid XML
|
||||||
|
* source
|
||||||
|
*
|
||||||
|
* @param privilegeConfigInputStream
|
||||||
|
* the XML stream containing the privilege configuration
|
||||||
|
*
|
||||||
|
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
|
||||||
|
* {@link PersistenceHandler} are set and initialized as well
|
||||||
|
*/
|
||||||
|
public static PrivilegeHandler initializeFromXml(InputStream privilegeConfigInputStream) {
|
||||||
|
|
||||||
|
// parse configuration file
|
||||||
|
PrivilegeContainerModel containerModel = new PrivilegeContainerModel();
|
||||||
|
PrivilegeConfigSaxReader xmlHandler = new PrivilegeConfigSaxReader(containerModel);
|
||||||
|
XmlHelper.parseDocument(privilegeConfigInputStream, xmlHandler);
|
||||||
|
|
||||||
|
return initializeFromXml(containerModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the {@link PrivilegeHandler} by initializing from the given {@link PrivilegeContainerModel}
|
||||||
|
*
|
||||||
|
* @param containerModel
|
||||||
|
* the configuration for the {@link PrivilegeHandler}
|
||||||
|
*
|
||||||
|
* @return the initialized {@link PrivilegeHandler} where the {@link EncryptionHandler} and
|
||||||
|
* {@link PersistenceHandler} are set and initialized as well
|
||||||
|
*/
|
||||||
|
public static PrivilegeHandler initializeFromXml(PrivilegeContainerModel containerModel) {
|
||||||
|
|
||||||
|
// initialize encryption handler
|
||||||
|
String encryptionHandlerClassName = containerModel.getEncryptionHandlerClassName();
|
||||||
|
EncryptionHandler encryptionHandler = ClassHelper.instantiateClass(encryptionHandlerClassName);
|
||||||
|
Map<String, String> parameterMap = containerModel.getEncryptionHandlerParameterMap();
|
||||||
|
try {
|
||||||
|
encryptionHandler.initialize(parameterMap);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = "EncryptionHandler {0} could not be initialized"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, encryptionHandlerClassName);
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize persistence handler
|
||||||
|
String persistenceHandlerClassName = containerModel.getPersistenceHandlerClassName();
|
||||||
|
PersistenceHandler persistenceHandler = ClassHelper.instantiateClass(persistenceHandlerClassName);
|
||||||
|
parameterMap = containerModel.getPersistenceHandlerParameterMap();
|
||||||
|
try {
|
||||||
|
persistenceHandler.initialize(parameterMap);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = "PersistenceHandler {0} could not be initialized"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, persistenceHandlerClassName);
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize privilege handler
|
||||||
|
DefaultPrivilegeHandler privilegeHandler = new DefaultPrivilegeHandler();
|
||||||
|
parameterMap = containerModel.getParameterMap();
|
||||||
|
Map<String, Class<PrivilegePolicy>> policyMap = containerModel.getPolicies();
|
||||||
|
try {
|
||||||
|
privilegeHandler.initialize(parameterMap, encryptionHandler, persistenceHandler, policyMap);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = "PrivilegeHandler {0} could not be initialized"; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeHandler.getClass().getName());
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return privilegeHandler;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constants used in parsing XML documents which contain the configuration for Privilege
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class XmlConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ROOT_PRIVILEGE_CONTAINER = "PrivilegeContainer" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ROOT_PRIVILEGE = "Privilege";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_CONTAINER = "Container" :
|
||||||
|
*/
|
||||||
|
public static final String XML_CONTAINER = "Container";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_POLICIES = "Policies" :
|
||||||
|
*/
|
||||||
|
public static final String XML_POLICIES = "Policies";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PRIVILEGES = "Privileges" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PRIVILEGES = "Privileges";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ROOT_PRIVILEGE_USERS_AND_ROLES = "UsersAndRoles" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ROOT_PRIVILEGE_USERS_AND_ROLES = "UsersAndRoles";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ROOT_CERTIFICATES = "Certificates" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ROOT_CERTIFICATES = "Certificates";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_HANDLER_PERSISTENCE = "PersistenceHandler" :
|
||||||
|
*/
|
||||||
|
public static final String XML_HANDLER_PERSISTENCE = "PersistenceHandler";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_HANDLER_ENCRYPTION = "EncryptionHandler" :
|
||||||
|
*/
|
||||||
|
public static final String XML_HANDLER_ENCRYPTION = "EncryptionHandler";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_HANDLER_PRIVILEGE = "PrivilegeHandler" :
|
||||||
|
*/
|
||||||
|
public static final String XML_HANDLER_PRIVILEGE = "PrivilegeHandler";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ROLES = "Roles" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ROLES = "Roles";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ROLE = "Role" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ROLE = "Role";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_USERS = "Users" :
|
||||||
|
*/
|
||||||
|
public static final String XML_USERS = "Users";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_CERTIFICATE = "Certificate" :
|
||||||
|
*/
|
||||||
|
public static final String XML_CERTIFICATE = "Certificate";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_SESSION_DATA = "SessionData" :
|
||||||
|
*/
|
||||||
|
public static final String XML_SESSION_DATA = "SessionData";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_USER = "User"
|
||||||
|
*/
|
||||||
|
public static final String XML_USER = "User";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PRIVILEGE = "Privilege" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PRIVILEGE = "Privilege";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_POLICY = "Policy" :
|
||||||
|
*/
|
||||||
|
public static final String XML_POLICY = "Policy";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PARAMETERS = "Parameters" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PARAMETERS = "Parameters";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PARAMETER = "Parameter" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PARAMETER = "Parameter";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PROPERTIES = "Properties" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PROPERTIES = "Properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PROPERTY = "Property" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PROPERTY = "Property";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ALL_ALLOWED = "AllAllowed" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ALL_ALLOWED = "AllAllowed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_DENY = "Deny" :
|
||||||
|
*/
|
||||||
|
public static final String XML_DENY = "Deny";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ALLOW = "Allow" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ALLOW = "Allow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_FIRSTNAME = "Firstname" :
|
||||||
|
*/
|
||||||
|
public static final String XML_FIRSTNAME = "Firstname";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_LASTNAME = "Lastname" :
|
||||||
|
*/
|
||||||
|
public static final String XML_LASTNAME = "Lastname";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_STATE = "State" :
|
||||||
|
*/
|
||||||
|
public static final String XML_STATE = "State";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_LOCALE = "Locale" :
|
||||||
|
*/
|
||||||
|
public static final String XML_LOCALE = "Locale";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_CLASS = "class" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_CLASS = "class";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_LOGIN_TIME = "loginTime" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_LOGIN_TIME = "loginTime";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_LAST_ACCESS = "lastAccess" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_LAST_ACCESS = "lastAccess";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_NAME = "name" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_NAME = "name";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_VALUE = "value" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_VALUE = "value";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_POLICY = "policy" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_POLICY = "policy";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_USER_ID = "userId" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_USER_ID = "userId";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_SESSION_ID = "sessionId" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_SESSION_ID = "sessionId";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_USERNAME = "username" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_USERNAME = "username";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_AUTH_TOKEN = "authToken" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_AUTH_TOKEN = "authToken";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_LOCALE = "locale" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_LOCALE = "locale";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_ATTR_PASSWORD = "password" :
|
||||||
|
*/
|
||||||
|
public static final String XML_ATTR_PASSWORD = "password";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PARAM_HASH_ALGORITHM = "hashAlgorithm" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PARAM_HASH_ALGORITHM = "hashAlgorithm";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PARAM_USERS_FILE = "usersXmlFile" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PARAM_USERS_FILE = "usersXmlFile";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PARAM_ROLES_FILE = "rolesXmlFile" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PARAM_ROLES_FILE = "rolesXmlFile";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML_PARAM_BASE_PATH = "basePath" :
|
||||||
|
*/
|
||||||
|
public static final String XML_PARAM_BASE_PATH = "basePath";
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.i18n;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PrivilegeMessages {
|
||||||
|
private static final String BUNDLE_NAME = "PrivilegeMessages"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
|
||||||
|
|
||||||
|
private PrivilegeMessages() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getString(String key) {
|
||||||
|
try {
|
||||||
|
return RESOURCE_BUNDLE.getString(key);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
return '!' + key + '!';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,316 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Certificate} is the object a client keeps when accessing a Privilege enabled system. This object is the
|
||||||
|
* instance which is always used when performing an access and is returned when a user performs a login through
|
||||||
|
* {@link PrivilegeHandler#authenticate(String, byte[])}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public final class Certificate implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final String sessionId;
|
||||||
|
private final String username;
|
||||||
|
private final String firstname;
|
||||||
|
private final String lastname;
|
||||||
|
private final UserState userState;
|
||||||
|
private final String authToken;
|
||||||
|
private final Date loginTime;
|
||||||
|
|
||||||
|
private final Set<String> userRoles;
|
||||||
|
private final Map<String, String> propertyMap;
|
||||||
|
|
||||||
|
private Locale locale;
|
||||||
|
private Date lastAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor initializing with all information needed for this certificate
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note, both the authentication token and password are private fields which are generated on login and only known
|
||||||
|
* by the {@link PrivilegeHandler}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param sessionId
|
||||||
|
* the users session id
|
||||||
|
* @param username
|
||||||
|
* the users login name
|
||||||
|
* @param firstname
|
||||||
|
* the users first name
|
||||||
|
* @param lastname
|
||||||
|
* the users last name
|
||||||
|
* @param authToken
|
||||||
|
* the authentication token defining the users unique session and is a private field of this certificate.
|
||||||
|
* @param locale
|
||||||
|
* the users {@link Locale}
|
||||||
|
* @param userRoles
|
||||||
|
* the user's roles
|
||||||
|
* @param propertyMap
|
||||||
|
* a {@link Map} containing string value pairs of properties for the logged in user. These properties can
|
||||||
|
* be edited and can be used for the user to change settings of this session
|
||||||
|
*/
|
||||||
|
public Certificate(String sessionId, String username, String firstname, String lastname, UserState userState,
|
||||||
|
String authToken, Date loginTime, Locale locale, Set<String> userRoles, Map<String, String> propertyMap) {
|
||||||
|
|
||||||
|
// validate arguments are not null
|
||||||
|
if (StringHelper.isEmpty(sessionId)) {
|
||||||
|
throw new PrivilegeException("sessionId is null!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(username)) {
|
||||||
|
throw new PrivilegeException("username is null!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(authToken)) {
|
||||||
|
throw new PrivilegeException("authToken is null!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (userState == null) {
|
||||||
|
throw new PrivilegeException("userState is null!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sessionId = sessionId;
|
||||||
|
this.username = username;
|
||||||
|
this.firstname = firstname;
|
||||||
|
this.lastname = lastname;
|
||||||
|
this.userState = userState;
|
||||||
|
this.authToken = authToken;
|
||||||
|
this.loginTime = loginTime;
|
||||||
|
|
||||||
|
// if no locale is given, set default
|
||||||
|
if (locale == null)
|
||||||
|
this.locale = Locale.getDefault();
|
||||||
|
else
|
||||||
|
this.locale = locale;
|
||||||
|
|
||||||
|
if (propertyMap == null)
|
||||||
|
this.propertyMap = Collections.emptyMap();
|
||||||
|
else
|
||||||
|
this.propertyMap = Collections.unmodifiableMap(propertyMap);
|
||||||
|
|
||||||
|
this.userRoles = Collections.unmodifiableSet(userRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set or roles this user has
|
||||||
|
*
|
||||||
|
* @return the user's roles
|
||||||
|
*/
|
||||||
|
public Set<String> getUserRoles() {
|
||||||
|
return this.userRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the user of this certificate has the given role
|
||||||
|
*
|
||||||
|
* @param role
|
||||||
|
* the role to check for
|
||||||
|
*
|
||||||
|
* @return true if the user of this certificate has the given role
|
||||||
|
*/
|
||||||
|
public boolean hasRole(String role) {
|
||||||
|
return this.userRoles.contains(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link User User's} property map. The map is immutable
|
||||||
|
*
|
||||||
|
* @return the propertyMap
|
||||||
|
*/
|
||||||
|
public Map<String, String> getPropertyMap() {
|
||||||
|
return this.propertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the property with the given key
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key for which the property is to be returned
|
||||||
|
*
|
||||||
|
* @return the value of the property with the given key, or null if it does not exist
|
||||||
|
*/
|
||||||
|
public String getProperty(String key) {
|
||||||
|
return this.propertyMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the locale
|
||||||
|
*/
|
||||||
|
public Locale getLocale() {
|
||||||
|
return this.locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param locale
|
||||||
|
* the locale to set
|
||||||
|
*/
|
||||||
|
public void setLocale(Locale locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sessionId
|
||||||
|
*/
|
||||||
|
public String getSessionId() {
|
||||||
|
return this.sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the username
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the firstname
|
||||||
|
*/
|
||||||
|
public String getFirstname() {
|
||||||
|
return this.firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastname
|
||||||
|
*/
|
||||||
|
public String getLastname() {
|
||||||
|
return this.lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the userState
|
||||||
|
*/
|
||||||
|
public UserState getUserState() {
|
||||||
|
return userState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the loginTime
|
||||||
|
*/
|
||||||
|
public Date getLoginTime() {
|
||||||
|
return this.loginTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the authToken if the given authPassword is correct, null otherwise
|
||||||
|
*
|
||||||
|
* @return the authToken if the given authPassword is correct, null otherwise
|
||||||
|
*/
|
||||||
|
public String getAuthToken() {
|
||||||
|
return this.authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastAccess
|
||||||
|
*/
|
||||||
|
public Date getLastAccess() {
|
||||||
|
return this.lastAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastAccess
|
||||||
|
* the lastAccess to set
|
||||||
|
*/
|
||||||
|
public void setLastAccess(Date lastAccess) {
|
||||||
|
this.lastAccess = lastAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Certificate [sessionId=");
|
||||||
|
builder.append(this.sessionId);
|
||||||
|
builder.append(", username=");
|
||||||
|
builder.append(this.username);
|
||||||
|
|
||||||
|
if (StringHelper.isNotEmpty(this.firstname)) {
|
||||||
|
builder.append(", firstname=");
|
||||||
|
builder.append(this.firstname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringHelper.isNotEmpty(this.lastname)) {
|
||||||
|
builder.append(", lastname=");
|
||||||
|
builder.append(this.lastname);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(", locale=");
|
||||||
|
builder.append(this.locale);
|
||||||
|
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.authToken == null) ? 0 : this.authToken.hashCode());
|
||||||
|
result = prime * result + ((this.locale == null) ? 0 : this.locale.hashCode());
|
||||||
|
result = prime * result + ((this.sessionId == null) ? 0 : this.sessionId.hashCode());
|
||||||
|
result = prime * result + ((this.username == null) ? 0 : this.username.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (!(obj instanceof Certificate))
|
||||||
|
return false;
|
||||||
|
Certificate other = (Certificate) obj;
|
||||||
|
if (this.authToken == null) {
|
||||||
|
if (other.authToken != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.authToken.equals(other.authToken))
|
||||||
|
return false;
|
||||||
|
if (this.locale == null) {
|
||||||
|
if (other.locale != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.locale.equals(other.locale))
|
||||||
|
return false;
|
||||||
|
if (this.sessionId == null) {
|
||||||
|
if (other.sessionId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.sessionId.equals(other.sessionId))
|
||||||
|
return false;
|
||||||
|
if (this.username == null) {
|
||||||
|
if (other.username != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.username.equals(other.username))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* {@link IPrivilege} is the main model object for Privilege. A {@link Role} has a set of Privileges assigned to it
|
||||||
|
* which defines the privileges a logged in user with that role has. If the {@link IPrivilege} has a
|
||||||
|
* {@link PrivilegePolicy} defined, then that policy will be used for finer granularity and with the deny and allow
|
||||||
|
* lists configured which is used to evaluate if privilege is granted to a {@link Restrictable}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IPrivilege {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link PrivilegeRep} which is a representation of this object used to serialize and view on clients
|
||||||
|
*/
|
||||||
|
public abstract PrivilegeRep asPrivilegeRep();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the policy
|
||||||
|
*/
|
||||||
|
public abstract String getPolicy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the allAllowed
|
||||||
|
*/
|
||||||
|
public abstract boolean isAllAllowed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the allowList
|
||||||
|
*/
|
||||||
|
public abstract Set<String> getAllowList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the denyList
|
||||||
|
*/
|
||||||
|
public abstract Set<String> getDenyList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if there are values in the allow list
|
||||||
|
*/
|
||||||
|
public abstract boolean hasAllowed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if the value is in the allow list
|
||||||
|
*/
|
||||||
|
public abstract boolean isAllowed(String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if there are values in the deny list
|
||||||
|
*/
|
||||||
|
public abstract boolean hasDenied();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the value is in the deny list
|
||||||
|
*/
|
||||||
|
public abstract boolean isDenied(String value);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This context gives access to a logged in user's privilege data e.g. the {@link UserRep}, {@link Certificate} and the
|
||||||
|
* user's list of {@link PrivilegeRep}
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: This is an internal object which is not to be serialized to clients
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeContext {
|
||||||
|
|
||||||
|
//
|
||||||
|
// object state
|
||||||
|
//
|
||||||
|
|
||||||
|
private UserRep userRep;
|
||||||
|
private Certificate certificate;
|
||||||
|
private Map<String, IPrivilege> privileges;
|
||||||
|
private Map<String, PrivilegePolicy> policies;
|
||||||
|
|
||||||
|
public PrivilegeContext(UserRep userRep, Certificate certificate, Map<String, IPrivilege> privileges,
|
||||||
|
Map<String, PrivilegePolicy> policies) {
|
||||||
|
this.userRep = userRep;
|
||||||
|
this.certificate = certificate;
|
||||||
|
this.privileges = Collections.unmodifiableMap(new HashMap<>(privileges));
|
||||||
|
this.policies = Collections.unmodifiableMap(new HashMap<>(policies));
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserRep getUserRep() {
|
||||||
|
return this.userRep;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Certificate getCertificate() {
|
||||||
|
return this.certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return this.userRep.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getPrivilegeNames() {
|
||||||
|
return this.privileges.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertHasPrivilege(String privilegeName) {
|
||||||
|
if (!this.privileges.containsKey(privilegeName)) {
|
||||||
|
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"), //$NON-NLS-1$
|
||||||
|
userRep.getUsername(), privilegeName);
|
||||||
|
throw new AccessDeniedException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPrivilege getPrivilege(String privilegeName) {
|
||||||
|
assertHasPrivilege(privilegeName);
|
||||||
|
return this.privileges.get(privilegeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivilegePolicy getPolicy(String policyName) {
|
||||||
|
PrivilegePolicy policy = this.policies.get(policyName);
|
||||||
|
if (policy == null) {
|
||||||
|
String msg = "The PrivilegePolicy {0} does not exist on the PrivilegeContext!"; //$NON-NLS-1$
|
||||||
|
throw new PrivilegeException(MessageFormat.format(msg, policyName));
|
||||||
|
}
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// business logic
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates if the user for this context has the privilege to access to the given {@link Restrictable}. If the user
|
||||||
|
* has the privilege, then this method returns with no exception and void, if the user does not have the privilege,
|
||||||
|
* then a {@link AccessDeniedException} is thrown.
|
||||||
|
*
|
||||||
|
* @param restrictable
|
||||||
|
* the {@link Restrictable} which the user wants to access
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if the user does not have access
|
||||||
|
* @throws PrivilegeException
|
||||||
|
* if there is an internal error due to wrongly configured privileges or programming errors
|
||||||
|
*/
|
||||||
|
public void validateAction(Restrictable restrictable) throws AccessDeniedException, PrivilegeException {
|
||||||
|
|
||||||
|
// the privilege for the restrictable
|
||||||
|
String privilegeName = restrictable.getPrivilegeName();
|
||||||
|
IPrivilege privilege = this.privileges.get(privilegeName);
|
||||||
|
if (privilege == null) {
|
||||||
|
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
|
||||||
|
getUsername(), privilegeName, restrictable.getClass().getName());
|
||||||
|
throw new AccessDeniedException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the policy referenced by the restrictable
|
||||||
|
String policyName = privilege.getPolicy();
|
||||||
|
PrivilegePolicy policy = getPolicy(policyName);
|
||||||
|
|
||||||
|
// delegate to the policy
|
||||||
|
policy.validateAction(this, privilege, restrictable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To keep certain details of the {@link IPrivilege} itself hidden from remote clients and make sure instances are only
|
||||||
|
* edited by users with the correct privilege, this representational version is allowed to be viewed by remote clients
|
||||||
|
* and simply wraps all public data from the {@link IPrivilege}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "Privilege")
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
public class PrivilegeRep implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "policy")
|
||||||
|
private String policy;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "allAllowed")
|
||||||
|
private boolean allAllowed;
|
||||||
|
|
||||||
|
@XmlElement(name = "denyList")
|
||||||
|
private Set<String> denyList;
|
||||||
|
|
||||||
|
@XmlElement(name = "allowList")
|
||||||
|
private Set<String> allowList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of this privilege, which is unique to all privileges known in the {@link PrivilegeHandler}
|
||||||
|
* @param policy
|
||||||
|
* the {@link PrivilegePolicy} configured to evaluate if the privilege is granted
|
||||||
|
* @param allAllowed
|
||||||
|
* a boolean defining if a {@link Role} with this {@link IPrivilege} has unrestricted access to a
|
||||||
|
* {@link Restrictable}
|
||||||
|
* @param denyList
|
||||||
|
* a list of deny rules for this {@link IPrivilege}
|
||||||
|
* @param allowList
|
||||||
|
* a list of allow rules for this {@link IPrivilege}
|
||||||
|
*/
|
||||||
|
public PrivilegeRep(String name, String policy, boolean allAllowed, Set<String> denyList, Set<String> allowList) {
|
||||||
|
this.name = name;
|
||||||
|
this.policy = policy;
|
||||||
|
this.allAllowed = allAllowed;
|
||||||
|
this.denyList = denyList;
|
||||||
|
this.allowList = allowList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private PrivilegeRep() {
|
||||||
|
// no-arg constructor for JAXB
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that all required fields are set
|
||||||
|
*/
|
||||||
|
public void validate() {
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(this.name)) {
|
||||||
|
throw new PrivilegeException("No name defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(this.policy)) {
|
||||||
|
throw new PrivilegeException("policy is null!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.denyList == null) {
|
||||||
|
throw new PrivilegeException("denyList is null"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (this.allowList == null) {
|
||||||
|
throw new PrivilegeException("allowList is null"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the policy
|
||||||
|
*/
|
||||||
|
public String getPolicy() {
|
||||||
|
return this.policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param policy
|
||||||
|
* the policy to set
|
||||||
|
*/
|
||||||
|
public void setPolicy(String policy) {
|
||||||
|
this.policy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the allAllowed
|
||||||
|
*/
|
||||||
|
public boolean isAllAllowed() {
|
||||||
|
return this.allAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param allAllowed
|
||||||
|
* the allAllowed to set
|
||||||
|
*/
|
||||||
|
public void setAllAllowed(boolean allAllowed) {
|
||||||
|
this.allAllowed = allAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the denyList
|
||||||
|
*/
|
||||||
|
public Set<String> getDenyList() {
|
||||||
|
return this.denyList == null ? new HashSet<>() : this.denyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param denyList
|
||||||
|
* the denyList to set
|
||||||
|
*/
|
||||||
|
public void setDenyList(Set<String> denyList) {
|
||||||
|
this.denyList = denyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the allowList
|
||||||
|
*/
|
||||||
|
public Set<String> getAllowList() {
|
||||||
|
return this.allowList == null ? new HashSet<>() : this.allowList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param allowList
|
||||||
|
* the allowList to set
|
||||||
|
*/
|
||||||
|
public void setAllowList(Set<String> allowList) {
|
||||||
|
this.allowList = allowList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("PrivilegeRep [name=");
|
||||||
|
builder.append(this.name);
|
||||||
|
builder.append(", policy=");
|
||||||
|
builder.append(this.policy);
|
||||||
|
builder.append(", allAllowed=");
|
||||||
|
builder.append(this.allAllowed);
|
||||||
|
builder.append(", denyList=");
|
||||||
|
builder.append((this.denyList == null ? "null" : this.denyList.size()));
|
||||||
|
builder.append(", allowList=");
|
||||||
|
builder.append((this.allowList == null ? "null" : this.allowList.size()));
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
PrivilegeRep other = (PrivilegeRep) obj;
|
||||||
|
if (this.name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Objects implementing this interface are used to grant/restrict privileges to them. A {@link PrivilegePolicy}
|
||||||
|
* implements the logic on granting/restricting privileges for a {@link Restrictable} and the
|
||||||
|
* {@link #getPrivilegeName()} is used to find the {@link IPrivilege} which has the associated {@link PrivilegePolicy}
|
||||||
|
* for evaluating access
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Restrictable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the {@link IPrivilege} which is to be used to validate privileges against
|
||||||
|
*
|
||||||
|
* @return the name of the {@link IPrivilege} which is to be used to validate privileges against
|
||||||
|
*/
|
||||||
|
public String getPrivilegeName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value which defines or describes what privilege is to be granted
|
||||||
|
*
|
||||||
|
* @return the value which defines or describes what privilege is to be granted
|
||||||
|
*/
|
||||||
|
public Object getPrivilegeValue();
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To keep certain details of the {@link Role} itself hidden from remote clients and make sure instances are only edited
|
||||||
|
* by users with the correct privilege, this representational version is allowed to be viewed by remote clients and
|
||||||
|
* simply wraps all public data from the {@link Role}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "Role")
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
public class RoleRep implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XmlElement(name = "privileges")
|
||||||
|
private List<PrivilegeRep> privileges;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of this role
|
||||||
|
* @param privileges
|
||||||
|
* the list of privileges granted to this role
|
||||||
|
*/
|
||||||
|
public RoleRep(String name, List<PrivilegeRep> privileges) {
|
||||||
|
this.name = name;
|
||||||
|
this.privileges = privileges;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private RoleRep() {
|
||||||
|
// no-arg constructor for JAXB
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validates that all required fields are set
|
||||||
|
*/
|
||||||
|
public void validate() {
|
||||||
|
if (StringHelper.isEmpty(this.name))
|
||||||
|
throw new PrivilegeException("name is null"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (this.privileges != null && !this.privileges.isEmpty()) {
|
||||||
|
for (PrivilegeRep privilege : this.privileges) {
|
||||||
|
try {
|
||||||
|
privilege.validate();
|
||||||
|
} catch (Exception e) {
|
||||||
|
String msg = "Privilege {0} is invalid on role {1}";
|
||||||
|
msg = MessageFormat.format(msg, privilege.getName(), this.name);
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the privileges assigned to this Role as a list
|
||||||
|
*
|
||||||
|
* @return the privileges assigned to this Role as a list
|
||||||
|
*/
|
||||||
|
public List<PrivilegeRep> getPrivileges() {
|
||||||
|
return this.privileges == null ? new ArrayList<>() : this.privileges;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the privileges on this from a list
|
||||||
|
*
|
||||||
|
* @param privileges
|
||||||
|
* the list of privileges to assign to this role
|
||||||
|
*/
|
||||||
|
public void setPrivileges(List<PrivilegeRep> privileges) {
|
||||||
|
this.privileges = privileges;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("RoleRep [name=");
|
||||||
|
builder.append(this.name);
|
||||||
|
builder.append(", privilegeMap=");
|
||||||
|
builder.append((this.privileges == null ? "null" : this.privileges));
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
RoleRep other = (RoleRep) obj;
|
||||||
|
if (this.name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.utils.dbc.DBC;
|
||||||
|
|
||||||
|
public class SimpleRestrictable implements Restrictable {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Object value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public SimpleRestrictable(String name, Object value) {
|
||||||
|
DBC.PRE.assertNotEmpty("name must not be emepty", name);
|
||||||
|
DBC.PRE.assertNotNull("value must not be null", value);
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrivilegeName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrivilegeValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,388 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
import ch.eitchnet.utils.xml.XmlKeyValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To keep certain details of the {@link User} itself hidden from remote clients and make sure instances are only edited
|
||||||
|
* by users with the correct privilege, this representational version is allowed to be viewed by remote clients and
|
||||||
|
* simply wraps all public data from the {@link User}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@XmlRootElement(name = "User")
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
public class UserRep implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "userId")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "username")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "firstname")
|
||||||
|
private String firstname;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "lastname")
|
||||||
|
private String lastname;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "userState")
|
||||||
|
private UserState userState;
|
||||||
|
|
||||||
|
@XmlAttribute(name = "locale")
|
||||||
|
private Locale locale;
|
||||||
|
|
||||||
|
@XmlElement(name = "roles")
|
||||||
|
private Set<String> roles;
|
||||||
|
|
||||||
|
@XmlElement(name = "properties")
|
||||||
|
private List<XmlKeyValue> properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* the user's id
|
||||||
|
* @param username
|
||||||
|
* the user's login name
|
||||||
|
* @param firstname
|
||||||
|
* the user's first name
|
||||||
|
* @param lastname
|
||||||
|
* the user's last name
|
||||||
|
* @param userState
|
||||||
|
* the user's {@link UserState}
|
||||||
|
* @param roles
|
||||||
|
* the set of {@link Role}s assigned to this user
|
||||||
|
* @param locale
|
||||||
|
* the user's {@link Locale}
|
||||||
|
* @param propertyMap
|
||||||
|
* a {@link Map} containing string value pairs of properties for this user
|
||||||
|
*/
|
||||||
|
public UserRep(String userId, String username, String firstname, String lastname, UserState userState,
|
||||||
|
Set<String> roles, Locale locale, Map<String, String> propertyMap) {
|
||||||
|
this.userId = userId;
|
||||||
|
this.username = username;
|
||||||
|
this.firstname = firstname;
|
||||||
|
this.lastname = lastname;
|
||||||
|
this.userState = userState;
|
||||||
|
this.roles = roles;
|
||||||
|
this.locale = locale;
|
||||||
|
this.properties = propertyMap == null ? new ArrayList<>() : XmlKeyValue.valueOf(propertyMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private UserRep() {
|
||||||
|
// No arg constructor for JAXB
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that all required fields are set
|
||||||
|
*/
|
||||||
|
public void validate() {
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(this.userId))
|
||||||
|
throw new PrivilegeException("userId is null or empty"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(this.username))
|
||||||
|
throw new PrivilegeException("username is null or empty"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (this.userState == null)
|
||||||
|
throw new PrivilegeException("userState is null"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(this.firstname))
|
||||||
|
throw new PrivilegeException("firstname is null or empty"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(this.lastname))
|
||||||
|
throw new PrivilegeException("lastname is null or empty"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (this.roles == null || this.roles.isEmpty())
|
||||||
|
throw new PrivilegeException("roles is null or empty"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the userId
|
||||||
|
*/
|
||||||
|
public String getUserId() {
|
||||||
|
return this.userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the userId
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* to set
|
||||||
|
*/
|
||||||
|
public void setUserId(String userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the username
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username
|
||||||
|
* the username to set
|
||||||
|
*/
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the firstname
|
||||||
|
*/
|
||||||
|
public String getFirstname() {
|
||||||
|
return this.firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param firstname
|
||||||
|
* the firstname to set
|
||||||
|
*/
|
||||||
|
public void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastname
|
||||||
|
*/
|
||||||
|
public String getLastname() {
|
||||||
|
return this.lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastname
|
||||||
|
* the lastname to set
|
||||||
|
*/
|
||||||
|
public void setLastname(String lastname) {
|
||||||
|
this.lastname = lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the userState
|
||||||
|
*/
|
||||||
|
public UserState getUserState() {
|
||||||
|
return this.userState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param userState
|
||||||
|
* the userState to set
|
||||||
|
*/
|
||||||
|
public void setUserState(UserState userState) {
|
||||||
|
this.userState = userState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the roles
|
||||||
|
*/
|
||||||
|
public Set<String> getRoles() {
|
||||||
|
return this.roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param roles
|
||||||
|
* the roles to set
|
||||||
|
*/
|
||||||
|
public void setRoles(Set<String> roles) {
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the locale
|
||||||
|
*/
|
||||||
|
public Locale getLocale() {
|
||||||
|
return this.locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param locale
|
||||||
|
* the locale to set
|
||||||
|
*/
|
||||||
|
public void setLocale(Locale locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the property with the given key
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key for which the property is to be returned
|
||||||
|
*
|
||||||
|
* @return the property with the given key, or null if the property is not defined
|
||||||
|
*/
|
||||||
|
public String getProperty(String key) {
|
||||||
|
if (this.properties == null)
|
||||||
|
return null;
|
||||||
|
for (XmlKeyValue keyValue : this.properties) {
|
||||||
|
if (keyValue.getKey().equals(key))
|
||||||
|
return keyValue.getValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the property with the key to the value
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key of the property to set
|
||||||
|
* @param value
|
||||||
|
* the value of the property to set
|
||||||
|
*/
|
||||||
|
public void setProperty(String key, String value) {
|
||||||
|
if (this.properties == null)
|
||||||
|
this.properties = new ArrayList<>();
|
||||||
|
|
||||||
|
boolean updated = false;
|
||||||
|
|
||||||
|
for (XmlKeyValue keyValue : this.properties) {
|
||||||
|
if (keyValue.getKey().equals(key)) {
|
||||||
|
keyValue.setValue(value);
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!updated) {
|
||||||
|
this.properties.add(new XmlKeyValue(key, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Set} of keys of all properties
|
||||||
|
*
|
||||||
|
* @return the {@link Set} of keys of all properties
|
||||||
|
*/
|
||||||
|
public Set<String> getPropertyKeySet() {
|
||||||
|
if (this.properties == null)
|
||||||
|
return new HashSet<>();
|
||||||
|
Set<String> keySet = new HashSet<>(this.properties.size());
|
||||||
|
for (XmlKeyValue keyValue : this.properties) {
|
||||||
|
keySet.add(keyValue.getKey());
|
||||||
|
}
|
||||||
|
return keySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of properties
|
||||||
|
*
|
||||||
|
* @return the map of properties
|
||||||
|
*/
|
||||||
|
public Map<String, String> getPropertyMap() {
|
||||||
|
if (this.properties == null)
|
||||||
|
return new HashMap<>();
|
||||||
|
return XmlKeyValue.toMap(this.properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string map properties of this user as a list of {@link XmlKeyValue} elements
|
||||||
|
*
|
||||||
|
* @return the string map properties of this user as a list of {@link XmlKeyValue} elements
|
||||||
|
*/
|
||||||
|
@XmlElement(name = "properties")
|
||||||
|
public List<XmlKeyValue> getProperties() {
|
||||||
|
return this.properties == null ? new ArrayList<>() : this.properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string map properties of this user from the given list of {@link XmlKeyValue}
|
||||||
|
*
|
||||||
|
* @param values
|
||||||
|
* the list of {@link XmlKeyValue} from which to set the properties
|
||||||
|
*/
|
||||||
|
public void setProperties(List<XmlKeyValue> values) {
|
||||||
|
this.properties = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("UserRep [userId=");
|
||||||
|
builder.append(this.userId);
|
||||||
|
builder.append(", username=");
|
||||||
|
builder.append(this.username);
|
||||||
|
builder.append(", firstname=");
|
||||||
|
builder.append(this.firstname);
|
||||||
|
builder.append(", lastname=");
|
||||||
|
builder.append(this.lastname);
|
||||||
|
builder.append(", userState=");
|
||||||
|
builder.append(this.userState);
|
||||||
|
builder.append(", locale=");
|
||||||
|
builder.append(this.locale);
|
||||||
|
builder.append(", roles=");
|
||||||
|
builder.append(this.roles);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.username == null) ? 0 : this.username.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
UserRep other = (UserRep) obj;
|
||||||
|
if (this.username == null) {
|
||||||
|
if (other.username != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.username.equals(other.username))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link UserState} enum defines the different states a {@link User} can have:
|
||||||
|
* <ul>
|
||||||
|
* <li>NEW - the user is new, and cannot login</li>
|
||||||
|
* <li>ENABLED - the user has been enabled, meaning a password has been set and the user has at least one role assigned
|
||||||
|
* and may thus login</li>
|
||||||
|
* <li>DISABLED - the user been disabled by an administrator</li>
|
||||||
|
* <li>EXPIRED - the user has automatically expired through a predefined time</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum UserState {
|
||||||
|
/**
|
||||||
|
* the user is new, and cannot login
|
||||||
|
*/
|
||||||
|
NEW,
|
||||||
|
/**
|
||||||
|
* the user has been enabled, meaning a password has been set and the user has at least one role assigned and may
|
||||||
|
* thus login
|
||||||
|
*/
|
||||||
|
ENABLED,
|
||||||
|
/**
|
||||||
|
* the user been disabled by an administrator
|
||||||
|
*/
|
||||||
|
DISABLED,
|
||||||
|
/**
|
||||||
|
* the user has automatically expired through a predefined time
|
||||||
|
*/
|
||||||
|
EXPIRED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the System user state which is special and thus exempted from normal uses
|
||||||
|
*/
|
||||||
|
SYSTEM;
|
||||||
|
|
||||||
|
public boolean isSystem() {
|
||||||
|
return this == UserState.SYSTEM;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model.internal;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used during XML parsing to hold the model before it is properly validated and made accessible through
|
||||||
|
* the {@link PrivilegeHandler}
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: This is an internal object which is not to be serialized or passed to clients
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeContainerModel {
|
||||||
|
|
||||||
|
private String encryptionHandlerClassName;
|
||||||
|
private Map<String, String> encryptionHandlerParameterMap;
|
||||||
|
private String persistenceHandlerClassName;
|
||||||
|
private Map<String, String> persistenceHandlerParameterMap;
|
||||||
|
private Map<String, String> parameterMap;
|
||||||
|
private Map<String, Class<PrivilegePolicy>> policies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*/
|
||||||
|
public PrivilegeContainerModel() {
|
||||||
|
this.policies = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parameterMap
|
||||||
|
*/
|
||||||
|
public Map<String, String> getParameterMap() {
|
||||||
|
return this.parameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param parameterMap
|
||||||
|
* the parameterMap to set
|
||||||
|
*/
|
||||||
|
public void setParameterMap(Map<String, String> parameterMap) {
|
||||||
|
this.parameterMap = parameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the encryptionHandlerClassName
|
||||||
|
*/
|
||||||
|
public String getEncryptionHandlerClassName() {
|
||||||
|
return this.encryptionHandlerClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param encryptionHandlerClassName
|
||||||
|
* the encryptionHandlerClassName to set
|
||||||
|
*/
|
||||||
|
public void setEncryptionHandlerClassName(String encryptionHandlerClassName) {
|
||||||
|
this.encryptionHandlerClassName = encryptionHandlerClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the encryptionHandlerParameterMap
|
||||||
|
*/
|
||||||
|
public Map<String, String> getEncryptionHandlerParameterMap() {
|
||||||
|
return this.encryptionHandlerParameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param encryptionHandlerParameterMap
|
||||||
|
* the encryptionHandlerParameterMap to set
|
||||||
|
*/
|
||||||
|
public void setEncryptionHandlerParameterMap(Map<String, String> encryptionHandlerParameterMap) {
|
||||||
|
this.encryptionHandlerParameterMap = encryptionHandlerParameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the persistenceHandlerClassName
|
||||||
|
*/
|
||||||
|
public String getPersistenceHandlerClassName() {
|
||||||
|
return this.persistenceHandlerClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param persistenceHandlerClassName
|
||||||
|
* the persistenceHandlerClassName to set
|
||||||
|
*/
|
||||||
|
public void setPersistenceHandlerClassName(String persistenceHandlerClassName) {
|
||||||
|
this.persistenceHandlerClassName = persistenceHandlerClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the persistenceHandlerParameterMap
|
||||||
|
*/
|
||||||
|
public Map<String, String> getPersistenceHandlerParameterMap() {
|
||||||
|
return this.persistenceHandlerParameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param persistenceHandlerParameterMap
|
||||||
|
* the persistenceHandlerParameterMap to set
|
||||||
|
*/
|
||||||
|
public void setPersistenceHandlerParameterMap(Map<String, String> persistenceHandlerParameterMap) {
|
||||||
|
this.persistenceHandlerParameterMap = persistenceHandlerParameterMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param privilegeName
|
||||||
|
* @param policyClassName
|
||||||
|
*/
|
||||||
|
public void addPolicy(String privilegeName, String policyClassName) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// load class and try to create a new instance
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<PrivilegePolicy> clazz = (Class<PrivilegePolicy>) Class.forName(policyClassName);
|
||||||
|
clazz.newInstance();
|
||||||
|
|
||||||
|
this.policies.put(privilegeName, clazz);
|
||||||
|
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
String msg = "Configured Privilege Policy {0} with class {1} could not be instantiated."; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeName, policyClassName);
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
String msg = "Configured Privilege Policy {0} with class {1} can not be accessed."; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeName, policyClassName);
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
String msg = "Configured Privilege Policy {0} with class {1} does not exist."; //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeName, policyClassName);
|
||||||
|
throw new PrivilegeException(msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the policies
|
||||||
|
*/
|
||||||
|
public Map<String, Class<PrivilegePolicy>> getPolicies() {
|
||||||
|
return this.policies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("PrivilegeContainerModel [encryptionHandlerClassName=");
|
||||||
|
builder.append(this.encryptionHandlerClassName);
|
||||||
|
builder.append(", encryptionHandlerParameterMap=");
|
||||||
|
builder.append(this.encryptionHandlerParameterMap.size());
|
||||||
|
builder.append(", persistenceHandlerClassName=");
|
||||||
|
builder.append(this.persistenceHandlerClassName);
|
||||||
|
builder.append(", persistenceHandlerParameterMap=");
|
||||||
|
builder.append(this.persistenceHandlerParameterMap.size());
|
||||||
|
builder.append(", parameterMap=");
|
||||||
|
builder.append(this.parameterMap.size());
|
||||||
|
builder.append(", policies=");
|
||||||
|
builder.append(this.policies.size());
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model.internal;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeRep;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* {@link IPrivilege} is the main model object for Privilege. A {@link Role} has a set of Privileges assigned to it
|
||||||
|
* which defines the privileges a logged in user with that role has. If the {@link IPrivilege} has a
|
||||||
|
* {@link PrivilegePolicy} defined, then that policy will be used for finer granularity and with the deny and allow
|
||||||
|
* lists configured which is used to evaluate if privilege is granted to a {@link Restrictable}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* {@link IPrivilege}s have allow and deny rules which the configured {@link PrivilegeHandler} uses to
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: This is an internal object which is not to be serialized or passed to clients, {@link PrivilegeRep}s are used
|
||||||
|
* for that
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public final class PrivilegeImpl implements IPrivilege {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String policy;
|
||||||
|
private final boolean allAllowed;
|
||||||
|
private final Set<String> denyList;
|
||||||
|
private final Set<String> allowList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of this privilege, which is unique to all privileges known in the {@link PrivilegeHandler}
|
||||||
|
* @param policy
|
||||||
|
* the {@link PrivilegePolicy} configured to evaluate if the privilege is granted. If null, then
|
||||||
|
* privilege is granted
|
||||||
|
* @param allAllowed
|
||||||
|
* a boolean defining if a {@link Role} with this {@link PrivilegeImpl} has unrestricted access to a
|
||||||
|
* {@link Restrictable} in which case the deny and allow lists are ignored and can be null
|
||||||
|
* @param denyList
|
||||||
|
* a list of deny rules for this {@link PrivilegeImpl}, can be null if all allowed
|
||||||
|
* @param allowList
|
||||||
|
* a list of allow rules for this {@link PrivilegeImpl}, can be null if all allowed
|
||||||
|
*/
|
||||||
|
public PrivilegeImpl(String name, String policy, boolean allAllowed, Set<String> denyList, Set<String> allowList) {
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(name)) {
|
||||||
|
throw new PrivilegeException("No name defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(policy)) {
|
||||||
|
throw new PrivilegeException(MessageFormat.format("Policy may not be empty for Privilege {0}!", name)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (denyList == null) {
|
||||||
|
throw new PrivilegeException(MessageFormat.format("denyList is null for Privilege {0}!", name)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (allowList == null) {
|
||||||
|
throw new PrivilegeException(MessageFormat.format("allowList is null for Privilege {0}!", name)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.allAllowed = allAllowed;
|
||||||
|
this.policy = policy;
|
||||||
|
this.denyList = Collections.unmodifiableSet(denyList);
|
||||||
|
this.allowList = Collections.unmodifiableSet(allowList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a {@link PrivilegeImpl} from the {@link PrivilegeRep}
|
||||||
|
*
|
||||||
|
* @param privilegeRep
|
||||||
|
* the {@link PrivilegeRep} from which to create the {@link PrivilegeImpl}
|
||||||
|
*/
|
||||||
|
public PrivilegeImpl(PrivilegeRep privilegeRep) {
|
||||||
|
this(privilegeRep.getName(), privilegeRep.getPolicy(), privilegeRep.isAllAllowed(), privilegeRep.getDenyList(),
|
||||||
|
privilegeRep.getAllowList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link PrivilegeRep} which is a representation of this object used to serialize and view on clients
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public PrivilegeRep asPrivilegeRep() {
|
||||||
|
return new PrivilegeRep(this.name, this.policy, this.allAllowed, new HashSet<>(this.denyList),
|
||||||
|
new HashSet<>(this.allowList));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the policy
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getPolicy() {
|
||||||
|
return this.policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the allAllowed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isAllAllowed() {
|
||||||
|
return this.allAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the allowList
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<String> getAllowList() {
|
||||||
|
return this.allowList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the denyList
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<String> getDenyList() {
|
||||||
|
return this.denyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if there are values in the allow list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasAllowed() {
|
||||||
|
return !this.allowList.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return if the value is in the allow list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isAllowed(String value) {
|
||||||
|
return this.allowList.contains(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if there are values in the deny list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasDenied() {
|
||||||
|
return !this.allowList.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the value is in the deny list
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isDenied(String value) {
|
||||||
|
return this.denyList.contains(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Privilege [name=");
|
||||||
|
builder.append(this.name);
|
||||||
|
builder.append(", policy=");
|
||||||
|
builder.append(this.policy);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
PrivilegeImpl other = (PrivilegeImpl) obj;
|
||||||
|
if (this.name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model.internal;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeRep;
|
||||||
|
import ch.eitchnet.privilege.model.RoleRep;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* A {@link User} is assigned a set of roles. These roles have a set of privileges assigned to them by name and they
|
||||||
|
* define the privileges granted to a user with this role
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: This is an internal object which is not to be serialized or passed to clients, {@link RoleRep}s are used for
|
||||||
|
* that
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public final class Role {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Map<String, IPrivilege> privilegeMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of the role
|
||||||
|
* @param privilegeMap
|
||||||
|
* a map of {@link IPrivilege}s granted to this role
|
||||||
|
*/
|
||||||
|
public Role(String name, Map<String, IPrivilege> privilegeMap) {
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(name)) {
|
||||||
|
throw new PrivilegeException("No name defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (privilegeMap == null) {
|
||||||
|
throw new PrivilegeException("No privileges defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.privilegeMap = Collections.unmodifiableMap(privilegeMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct {@link Role} from its representation {@link RoleRep}
|
||||||
|
*
|
||||||
|
* @param roleRep
|
||||||
|
* the representation from which to create the {@link Role}
|
||||||
|
*/
|
||||||
|
public Role(RoleRep roleRep) {
|
||||||
|
|
||||||
|
String name = roleRep.getName();
|
||||||
|
if (StringHelper.isEmpty(name)) {
|
||||||
|
throw new PrivilegeException("No name defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roleRep.getPrivileges() == null) {
|
||||||
|
throw new PrivilegeException("Privileges may not be null!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
// build privileges from rep
|
||||||
|
Map<String, IPrivilege> privilegeMap = new HashMap<>(roleRep.getPrivileges().size());
|
||||||
|
for (PrivilegeRep privilege : roleRep.getPrivileges()) {
|
||||||
|
privilegeMap.put(privilege.getName(), new PrivilegeImpl(privilege));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
|
this.privilegeMap = Collections.unmodifiableMap(privilegeMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Set} of names for the currently stored {@link IPrivilege Privileges}
|
||||||
|
*
|
||||||
|
* @return the {@link Set} of names for the currently stored {@link IPrivilege Privileges}
|
||||||
|
*/
|
||||||
|
public Set<String> getPrivilegeNames() {
|
||||||
|
return this.privilegeMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link IPrivilege} for the given name, null if it does not exist
|
||||||
|
*
|
||||||
|
* @return the {@link IPrivilege} for the given name, null if it does not exist
|
||||||
|
*/
|
||||||
|
public IPrivilege getPrivilege(String name) {
|
||||||
|
return this.privilegeMap.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this {@link Role} has the {@link IPrivilege} with the given name
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of the {@link IPrivilege}
|
||||||
|
*
|
||||||
|
* @return true if this {@link Role} has the {@link IPrivilege} with the given name
|
||||||
|
*/
|
||||||
|
public boolean hasPrivilege(String name) {
|
||||||
|
return this.privilegeMap.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link RoleRep} which is a representation of this object used to serialize and view on clients
|
||||||
|
*/
|
||||||
|
public RoleRep asRoleRep() {
|
||||||
|
List<PrivilegeRep> privileges = new ArrayList<>();
|
||||||
|
for (Entry<String, IPrivilege> entry : this.privilegeMap.entrySet()) {
|
||||||
|
privileges.add(entry.getValue().asPrivilegeRep());
|
||||||
|
}
|
||||||
|
return new RoleRep(this.name, privileges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("Role [name=");
|
||||||
|
builder.append(this.name);
|
||||||
|
builder.append(", privileges=");
|
||||||
|
builder.append(this.privilegeMap.keySet());
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Role other = (Role) obj;
|
||||||
|
if (this.name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.model.internal;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.model.UserRep;
|
||||||
|
import ch.eitchnet.privilege.model.UserState;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class defines the actual login information for a given user which can be granted privileges. Every user is
|
||||||
|
* granted a set of {@link Role}s and has a {@link UserState} including detail information like first name and lastname
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note: This is an internal object which is not to be serialized or passed to clients, {@link UserRep}s are used for
|
||||||
|
* that
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public final class User {
|
||||||
|
|
||||||
|
private final String userId;
|
||||||
|
|
||||||
|
private final String username;
|
||||||
|
private final String password;
|
||||||
|
|
||||||
|
private final String firstname;
|
||||||
|
private final String lastname;
|
||||||
|
|
||||||
|
private final UserState userState;
|
||||||
|
|
||||||
|
private final Set<String> roles;
|
||||||
|
|
||||||
|
private final Map<String, String> propertyMap;
|
||||||
|
|
||||||
|
private final Locale locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param userId
|
||||||
|
* the user's id
|
||||||
|
* @param username
|
||||||
|
* the user's login name
|
||||||
|
* @param password
|
||||||
|
* the user's password (hashed)
|
||||||
|
* @param firstname
|
||||||
|
* the user's first name
|
||||||
|
* @param lastname
|
||||||
|
* the user's lastname
|
||||||
|
* @param userState
|
||||||
|
* the user's {@link UserState}
|
||||||
|
* @param roles
|
||||||
|
* the set of {@link Role}s assigned to this user
|
||||||
|
* @param locale
|
||||||
|
* the user's {@link Locale}
|
||||||
|
* @param propertyMap
|
||||||
|
* a {@link Map} containing string value pairs of properties for this user
|
||||||
|
*/
|
||||||
|
public User(String userId, String username, String password, String firstname, String lastname,
|
||||||
|
UserState userState, Set<String> roles, Locale locale, Map<String, String> propertyMap) {
|
||||||
|
|
||||||
|
if (StringHelper.isEmpty(userId)) {
|
||||||
|
throw new PrivilegeException("No UserId defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (userState == null) {
|
||||||
|
throw new PrivilegeException("No userState defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(username)) {
|
||||||
|
throw new PrivilegeException("No username defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (userState != UserState.SYSTEM) {
|
||||||
|
if (StringHelper.isEmpty(lastname)) {
|
||||||
|
throw new PrivilegeException("No lastname defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(firstname)) {
|
||||||
|
throw new PrivilegeException("No firstname defined!"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// password may be null, meaning not able to login
|
||||||
|
// roles may be null, meaning not able to login and must be added later
|
||||||
|
// locale may be null, meaning use system default
|
||||||
|
// properties may be null, meaning no properties
|
||||||
|
|
||||||
|
this.userId = userId;
|
||||||
|
|
||||||
|
this.username = username;
|
||||||
|
this.password = StringHelper.isEmpty(password) ? null : password;
|
||||||
|
this.userState = userState;
|
||||||
|
|
||||||
|
this.firstname = firstname;
|
||||||
|
this.lastname = lastname;
|
||||||
|
|
||||||
|
if (roles == null)
|
||||||
|
this.roles = Collections.emptySet();
|
||||||
|
else
|
||||||
|
this.roles = Collections.unmodifiableSet(new HashSet<>(roles));
|
||||||
|
|
||||||
|
if (locale == null)
|
||||||
|
this.locale = Locale.getDefault();
|
||||||
|
else
|
||||||
|
this.locale = locale;
|
||||||
|
|
||||||
|
if (propertyMap == null)
|
||||||
|
this.propertyMap = Collections.emptyMap();
|
||||||
|
else
|
||||||
|
this.propertyMap = Collections.unmodifiableMap(new HashMap<>(propertyMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the userId
|
||||||
|
*/
|
||||||
|
public String getUserId() {
|
||||||
|
return this.userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the username
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hashed password for this {@link User}
|
||||||
|
*
|
||||||
|
* @return the hashed password for this {@link User}
|
||||||
|
*/
|
||||||
|
public String getPassword() {
|
||||||
|
return this.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the first name
|
||||||
|
*/
|
||||||
|
public String getFirstname() {
|
||||||
|
return this.firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the last name
|
||||||
|
*/
|
||||||
|
public String getLastname() {
|
||||||
|
return this.lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the userState
|
||||||
|
*/
|
||||||
|
public UserState getUserState() {
|
||||||
|
return this.userState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the roles
|
||||||
|
*/
|
||||||
|
public Set<String> getRoles() {
|
||||||
|
return this.roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this user has the specified role
|
||||||
|
*
|
||||||
|
* @param role
|
||||||
|
* the name of the {@link Role} to check for
|
||||||
|
*
|
||||||
|
* @return true if the this user has the specified role
|
||||||
|
*/
|
||||||
|
public boolean hasRole(String role) {
|
||||||
|
return this.roles.contains(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the locale
|
||||||
|
*/
|
||||||
|
public Locale getLocale() {
|
||||||
|
return this.locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the property with the given key
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key for which the property is to be returned
|
||||||
|
*
|
||||||
|
* @return the property with the given key, or null if the property is not defined
|
||||||
|
*/
|
||||||
|
public String getProperty(String key) {
|
||||||
|
return this.propertyMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Set} of keys of all properties
|
||||||
|
*
|
||||||
|
* @return the {@link Set} of keys of all properties
|
||||||
|
*/
|
||||||
|
public Set<String> getPropertyKeySet() {
|
||||||
|
return this.propertyMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of properties
|
||||||
|
*
|
||||||
|
* @return the map of properties
|
||||||
|
*/
|
||||||
|
public Map<String, String> getProperties() {
|
||||||
|
return this.propertyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link UserRep} which is a representation of this object used to serialize and view on clients
|
||||||
|
*/
|
||||||
|
public UserRep asUserRep() {
|
||||||
|
return new UserRep(this.userId, this.username, this.firstname, this.lastname, this.userState,
|
||||||
|
new HashSet<>(this.roles), this.locale, new HashMap<>(this.propertyMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this object displaying its concrete type and its values
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("User [userId=");
|
||||||
|
builder.append(this.userId);
|
||||||
|
builder.append(", username=");
|
||||||
|
builder.append(this.username);
|
||||||
|
builder.append(", firstname=");
|
||||||
|
builder.append(this.firstname);
|
||||||
|
builder.append(", lastname=");
|
||||||
|
builder.append(this.lastname);
|
||||||
|
builder.append(", locale=");
|
||||||
|
builder.append(this.locale);
|
||||||
|
builder.append(", userState=");
|
||||||
|
builder.append(this.userState);
|
||||||
|
builder.append(", roles=");
|
||||||
|
builder.append(this.roles);
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((this.userId == null) ? 0 : this.userId.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
User other = (User) obj;
|
||||||
|
if (this.userId == null) {
|
||||||
|
if (other.userId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!this.userId.equals(other.userId))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a simple implementation of {@link PrivilegePolicy} which uses the {@link Restrictable#getPrivilegeName()} to
|
||||||
|
* see if a given {@link Role} has the privilege required by the value from {@link Restrictable#getPrivilegeValue()}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class DefaultPrivilege implements PrivilegePolicy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of {@link Restrictable#getPrivilegeValue()} is used to check if the {@link Role} has this privilege
|
||||||
|
*
|
||||||
|
* @see ch.eitchnet.privilege.policy.PrivilegePolicy#validateAction(IPrivilege, Restrictable)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||||
|
|
||||||
|
// get the value on which the action is to be performed
|
||||||
|
Object object = restrictable.getPrivilegeValue();
|
||||||
|
|
||||||
|
// DefaultPrivilege policy expects the privilege value to be a string
|
||||||
|
if (!(object instanceof String)) {
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.illegalArgument.nonstring"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if everything is allowed, then no need to carry on
|
||||||
|
if (privilege.isAllAllowed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
String privilegeValue = (String) object;
|
||||||
|
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* {@link PrivilegePolicy} implements logic to determine if a {@link User} which has the given {@link Role} and the
|
||||||
|
* given {@link IPrivilege} has access to the given {@link Restrictable}
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* TODO
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public interface PrivilegePolicy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given {@link Role} and the given {@link IPrivilege} has access to the given {@link Restrictable}
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* the privilege context
|
||||||
|
* @param privilege
|
||||||
|
* the {@link IPrivilege} containing the permissions
|
||||||
|
* @param restrictable
|
||||||
|
* the {@link Restrictable} to which the user wants access
|
||||||
|
*
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* if action not allowed
|
||||||
|
*/
|
||||||
|
public abstract void validateAction(PrivilegeContext context, IPrivilege privilege, Restrictable restrictable)
|
||||||
|
throws AccessDeniedException;
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegePolicyHelper {
|
||||||
|
|
||||||
|
public static String preValidate(IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
if (privilege == null)
|
||||||
|
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.privilegeNull")); //$NON-NLS-1$
|
||||||
|
if (restrictable == null)
|
||||||
|
throw new PrivilegeException(PrivilegeMessages.getString("Privilege.restrictableNull")); //$NON-NLS-1$
|
||||||
|
|
||||||
|
// get the PrivilegeName
|
||||||
|
String privilegeName = restrictable.getPrivilegeName();
|
||||||
|
if (StringHelper.isEmpty(privilegeName)) {
|
||||||
|
String msg = PrivilegeMessages.getString("Privilege.privilegeNameEmpty"); //$NON-NLS-1$
|
||||||
|
throw new PrivilegeException(MessageFormat.format(msg, restrictable));
|
||||||
|
}
|
||||||
|
|
||||||
|
// we want the privileges names to match
|
||||||
|
if (!privilege.getName().equals(privilegeName)) {
|
||||||
|
throw new PrivilegeException(MessageFormat.format(
|
||||||
|
PrivilegeMessages.getString("Privilege.illegalArgument.privilegeNameMismatch"), //$NON-NLS-1$
|
||||||
|
privilege.getName(), privilegeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return privilegeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param privilege
|
||||||
|
* @param privilegeValue
|
||||||
|
*/
|
||||||
|
public static void checkByAllowDenyValues(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable,
|
||||||
|
String privilegeValue) {
|
||||||
|
|
||||||
|
// first check values not allowed
|
||||||
|
if (privilege.isDenied(privilegeValue)) {
|
||||||
|
// then throw access denied
|
||||||
|
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
|
||||||
|
ctx.getUsername(), privilege.getName(), restrictable.getClass().getName());
|
||||||
|
throw new AccessDeniedException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check values allowed
|
||||||
|
if (privilege.isAllowed(privilegeValue))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// default is not allowed
|
||||||
|
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.accessdenied.noprivilege"), //$NON-NLS-1$
|
||||||
|
ctx.getUsername(), privilege.getName(), restrictable.getClass().getName());
|
||||||
|
throw new AccessDeniedException(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.utils.collections.Tuple;
|
||||||
|
import ch.eitchnet.utils.dbc.DBC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link PrivilegePolicy} expects a {@link Tuple} as {@link Restrictable#getPrivilegeValue()}. The Tuple must
|
||||||
|
* contain {@link Role} as first and second value. Then the policy decides depending on the user specific privileges
|
||||||
|
* (see {@link PrivilegeHandler}), uses the basic <code>Allow</code> and <code>Deny</code> to detect if the username of
|
||||||
|
* the certificate is allowed
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class RoleAccessPrivilege implements PrivilegePolicy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||||
|
|
||||||
|
// get the value on which the action is to be performed
|
||||||
|
Object object = restrictable.getPrivilegeValue();
|
||||||
|
|
||||||
|
// if the object is null, then it means the validation is that the privilege must exist
|
||||||
|
if (object == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// RoleAccessPrivilege policy expects the privilege value to be a role
|
||||||
|
if (!(object instanceof Tuple)) {
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.illegalArgument.nontuple"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if everything is allowed, then no need to carry on
|
||||||
|
if (privilege.isAllAllowed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tuple tuple = (Tuple) object;
|
||||||
|
|
||||||
|
// get role name as privilege value
|
||||||
|
Role oldRole = tuple.getFirst();
|
||||||
|
Role newRole = tuple.getSecond();
|
||||||
|
|
||||||
|
switch (privilegeName) {
|
||||||
|
case PrivilegeHandler.PRIVILEGE_GET_ROLE: {
|
||||||
|
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
|
||||||
|
|
||||||
|
String privilegeValue = newRole.getName();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrivilegeHandler.PRIVILEGE_ADD_ROLE: {
|
||||||
|
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
|
||||||
|
|
||||||
|
String privilegeValue = newRole.getName();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_MODIFY_ROLE: {
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldRole);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
|
||||||
|
|
||||||
|
String privilegeValue = newRole.getName();
|
||||||
|
DBC.INTERIM.assertEquals("oldRole and newRole names must be the same", oldRole.getName(), privilegeValue);
|
||||||
|
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE: {
|
||||||
|
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldRole);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newRole);
|
||||||
|
|
||||||
|
String privilegeValue = newRole.getName();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.roleAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeName);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.utils.collections.Tuple;
|
||||||
|
import ch.eitchnet.utils.dbc.DBC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link PrivilegePolicy} expects a {@link Tuple} as {@link Restrictable#getPrivilegeValue()} and then depending
|
||||||
|
* on the user specific privileges (see {@link PrivilegeHandler}), uses the basic <code>Allow</code> and
|
||||||
|
* <code>Deny</code> to detect if the username of the certificate is allowed
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class UserAccessPrivilege implements PrivilegePolicy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||||
|
|
||||||
|
// get the value on which the action is to be performed
|
||||||
|
Object object = restrictable.getPrivilegeValue();
|
||||||
|
|
||||||
|
// if the object is null, then it means the validation is that the privilege must exist
|
||||||
|
if (object == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// RoleAccessPrivilege policy expects the privilege value to be a role
|
||||||
|
if (!(object instanceof Tuple)) {
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.illegalArgument.nontuple"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if everything is allowed, then no need to carry on
|
||||||
|
if (privilege.isAllAllowed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tuple tuple = (Tuple) object;
|
||||||
|
|
||||||
|
switch (privilegeName) {
|
||||||
|
case PrivilegeHandler.PRIVILEGE_GET_USER: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUsername();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_ADD_USER: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUsername();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_REMOVE_USER: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNull("For " + privilegeName + " first must be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUsername();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_MODIFY_USER: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUsername();
|
||||||
|
DBC.INTERIM.assertEquals("oldUser and newUser names must be the same", oldUser.getUsername(),
|
||||||
|
privilegeValue);
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER: {
|
||||||
|
User user = tuple.getFirst();
|
||||||
|
String roleName = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName);
|
||||||
|
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, roleName);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER: {
|
||||||
|
User user = tuple.getFirst();
|
||||||
|
String roleName = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", roleName);
|
||||||
|
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, roleName);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_SET_USER_STATE: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUserState().name();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUsername();
|
||||||
|
|
||||||
|
// user can set their own locale
|
||||||
|
if (ctx.getUsername().equals(privilegeValue))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD: {
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", oldUser);
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
|
||||||
|
String privilegeValue = newUser.getUsername();
|
||||||
|
|
||||||
|
// user can set their own password
|
||||||
|
if (ctx.getUsername().equals(privilegeValue))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
String msg = PrivilegeMessages.getString("Privilege.userAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeName, this.getClass().getName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.utils.collections.Tuple;
|
||||||
|
import ch.eitchnet.utils.dbc.DBC;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that any access to a privilege User is done only by users in the same organisation
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class UserAccessWithSameOrganisationPrivilege extends UserAccessPrivilege {
|
||||||
|
|
||||||
|
private static final String PARAM_ORGANISATION = "organisation";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
String privilegeName = PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||||
|
|
||||||
|
// get the value on which the action is to be performed
|
||||||
|
Object object = restrictable.getPrivilegeValue();
|
||||||
|
|
||||||
|
// RoleAccessPrivilege policy expects the privilege value to be a role
|
||||||
|
if (!(object instanceof Tuple)) {
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.illegalArgument.nontuple"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get user organisation
|
||||||
|
String userOrg = ctx.getCertificate().getProperty(PARAM_ORGANISATION);
|
||||||
|
if (StringHelper.isEmpty(userOrg)) {
|
||||||
|
throw new AccessDeniedException("No organisation configured for user " + ctx.getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
Tuple tuple = (Tuple) object;
|
||||||
|
|
||||||
|
switch (privilegeName) {
|
||||||
|
case PrivilegeHandler.PRIVILEGE_GET_USER:
|
||||||
|
case PrivilegeHandler.PRIVILEGE_ADD_USER:
|
||||||
|
case PrivilegeHandler.PRIVILEGE_MODIFY_USER:
|
||||||
|
case PrivilegeHandler.PRIVILEGE_REMOVE_USER: {
|
||||||
|
|
||||||
|
// make sure old user has same organisation
|
||||||
|
User oldUser = tuple.getFirst();
|
||||||
|
if (oldUser != null) {
|
||||||
|
String oldOrg = oldUser.getProperty(PARAM_ORGANISATION);
|
||||||
|
if (!userOrg.equals(oldOrg)) {
|
||||||
|
throw new AccessDeniedException("User " + ctx.getUsername()
|
||||||
|
+ " may not access users outside of their organisation: " + userOrg + " / " + oldOrg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure new user has same organisation
|
||||||
|
User newUser = tuple.getSecond();
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " second must not be null!", newUser);
|
||||||
|
String newdOrg = newUser.getProperty(PARAM_ORGANISATION);
|
||||||
|
if (!userOrg.equals(newdOrg)) {
|
||||||
|
throw new AccessDeniedException("User " + ctx.getUsername()
|
||||||
|
+ " may not access users outside of their organisations: " + userOrg + " / " + newdOrg);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER:
|
||||||
|
case PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER: {
|
||||||
|
|
||||||
|
User user = tuple.getFirst();
|
||||||
|
DBC.INTERIM.assertNotNull("For " + privilegeName + " first must not be null!", user);
|
||||||
|
String org = user.getProperty(PARAM_ORGANISATION);
|
||||||
|
if (!userOrg.equals(org)) {
|
||||||
|
throw new AccessDeniedException("User " + ctx.getUsername()
|
||||||
|
+ " may not access users outside of their organisation: " + userOrg + " / " + org);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.userAccessPrivilege.unknownPrivilege"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, privilegeName);
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now delegate the rest of the validation to the super class
|
||||||
|
super.validateAction(ctx, privilege, restrictable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This {@link PrivilegePolicy} expects a {@link Certificate} as {@link Restrictable#getPrivilegeValue()} and uses the
|
||||||
|
* basic <code>Allow</code> and <code>Deny</code> to detect if the username of the certificate is allowed.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The {@link Certificate} as privilegeValue is not to be confused with the {@link Certificate} of the current user.
|
||||||
|
* This certificate is of the user to which access is request, i.e. modifying the session of a logged in user.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class UsernameFromCertificatePrivilege implements PrivilegePolicy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||||
|
|
||||||
|
// get the value on which the action is to be performed
|
||||||
|
Object object = restrictable.getPrivilegeValue();
|
||||||
|
|
||||||
|
// RoleAccessPrivilege policy expects the privilege value to be a role
|
||||||
|
if (!(object instanceof Certificate)) {
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.illegalArgument.noncertificate"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if everything is allowed, then no need to carry on
|
||||||
|
if (privilege.isAllAllowed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Certificate cert = (Certificate) object;
|
||||||
|
String privilegeValue = cert.getUsername();
|
||||||
|
PrivilegePolicyHelper.checkByAllowDenyValues(ctx, privilege, restrictable, privilegeValue);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.policy;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This {@link PrivilegePolicy} expects a {@link Certificate} as {@link Restrictable#getPrivilegeValue()} and uses the
|
||||||
|
* basic <code>Allow</code> and <code>Deny</code> to detect if the username of the certificate is allowed.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The {@link Certificate} as privilegeValue is not to be confused with the {@link Certificate} of the current user.
|
||||||
|
* This certificate is of the user to which access is request, i.e. modifying the session of a logged in user.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class UsernameFromCertificateWithSameOrganisationPrivilege extends UsernameFromCertificatePrivilege {
|
||||||
|
|
||||||
|
private static final String PARAM_ORGANISATION = "organisation";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateAction(PrivilegeContext ctx, IPrivilege privilege, Restrictable restrictable) {
|
||||||
|
PrivilegePolicyHelper.preValidate(privilege, restrictable);
|
||||||
|
|
||||||
|
// get the value on which the action is to be performed
|
||||||
|
Object object = restrictable.getPrivilegeValue();
|
||||||
|
|
||||||
|
// RoleAccessPrivilege policy expects the privilege value to be a role
|
||||||
|
if (!(object instanceof Certificate)) {
|
||||||
|
String msg = Restrictable.class.getName()
|
||||||
|
+ PrivilegeMessages.getString("Privilege.illegalArgument.noncertificate"); //$NON-NLS-1$
|
||||||
|
msg = MessageFormat.format(msg, restrictable.getClass().getSimpleName());
|
||||||
|
throw new PrivilegeException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get object
|
||||||
|
Certificate cert = (Certificate) object;
|
||||||
|
|
||||||
|
// get user organisation
|
||||||
|
String userOrg = ctx.getCertificate().getProperty(PARAM_ORGANISATION);
|
||||||
|
if (StringHelper.isEmpty(userOrg)) {
|
||||||
|
throw new AccessDeniedException("No organisation configured for user " + ctx.getUsername());
|
||||||
|
}
|
||||||
|
// assert same organisation
|
||||||
|
String org = cert.getProperty(PARAM_ORGANISATION);
|
||||||
|
if (!userOrg.equals(org)) {
|
||||||
|
throw new AccessDeniedException("User " + ctx.getUsername()
|
||||||
|
+ " may not access users outside of their organisation: " + userOrg + " / " + org);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now delegate the rest of the validation to the super class
|
||||||
|
super.validateAction(ctx, privilege, restrictable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class CertificateStubsDomWriter {
|
||||||
|
|
||||||
|
private List<Certificate> certificates;
|
||||||
|
private OutputStream outputStream;
|
||||||
|
|
||||||
|
public CertificateStubsDomWriter(List<Certificate> certificates, OutputStream outputStream) {
|
||||||
|
this.certificates = certificates;
|
||||||
|
this.outputStream = outputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write() {
|
||||||
|
|
||||||
|
// create document root
|
||||||
|
Document doc = XmlHelper.createDocument();
|
||||||
|
Element rootElement = doc.createElement(XmlConstants.XML_ROOT_CERTIFICATES);
|
||||||
|
doc.appendChild(rootElement);
|
||||||
|
|
||||||
|
this.certificates.stream().sorted((c1, c2) -> c1.getSessionId().compareTo(c2.getSessionId())).forEach(cert -> {
|
||||||
|
|
||||||
|
// create the certificate element
|
||||||
|
Element certElement = doc.createElement(XmlConstants.XML_CERTIFICATE);
|
||||||
|
rootElement.appendChild(certElement);
|
||||||
|
|
||||||
|
// sessionId;
|
||||||
|
certElement.setAttribute(XmlConstants.XML_ATTR_SESSION_ID, cert.getSessionId());
|
||||||
|
|
||||||
|
// username;
|
||||||
|
certElement.setAttribute(XmlConstants.XML_ATTR_USERNAME, cert.getUsername());
|
||||||
|
|
||||||
|
// authToken;
|
||||||
|
certElement.setAttribute(XmlConstants.XML_ATTR_AUTH_TOKEN, cert.getAuthToken());
|
||||||
|
|
||||||
|
// locale;
|
||||||
|
certElement.setAttribute(XmlConstants.XML_ATTR_LOCALE, cert.getLocale().toString());
|
||||||
|
|
||||||
|
// loginTime;
|
||||||
|
certElement.setAttribute(XmlConstants.XML_ATTR_LOGIN_TIME,
|
||||||
|
ISO8601FormatFactory.getInstance().formatDate(cert.getLoginTime()));
|
||||||
|
|
||||||
|
// lastAccess;
|
||||||
|
certElement.setAttribute(XmlConstants.XML_ATTR_LAST_ACCESS,
|
||||||
|
ISO8601FormatFactory.getInstance().formatDate(cert.getLastAccess()));
|
||||||
|
});
|
||||||
|
|
||||||
|
// write the container file to disk
|
||||||
|
XmlHelper.writeDocument(doc, this.outputStream);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.utils.dbc.DBC;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class CertificateStubsSaxReader extends DefaultHandler {
|
||||||
|
|
||||||
|
private InputStream inputStream;
|
||||||
|
private List<CertificateStub> stubs;
|
||||||
|
|
||||||
|
public CertificateStubsSaxReader(InputStream inputStream) {
|
||||||
|
this.inputStream = inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CertificateStub> read() {
|
||||||
|
this.stubs = new ArrayList<>();
|
||||||
|
XmlHelper.parseDocument(this.inputStream, this);
|
||||||
|
return stubs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
|
||||||
|
switch (qName) {
|
||||||
|
case XmlConstants.XML_ROOT_CERTIFICATES:
|
||||||
|
break;
|
||||||
|
case XmlConstants.XML_CERTIFICATE:
|
||||||
|
|
||||||
|
CertificateStub stub = new CertificateStub();
|
||||||
|
stub.sessionId = attributes.getValue(XmlConstants.XML_ATTR_SESSION_ID);
|
||||||
|
stub.username = attributes.getValue(XmlConstants.XML_ATTR_USERNAME);
|
||||||
|
stub.authToken = attributes.getValue(XmlConstants.XML_ATTR_AUTH_TOKEN);
|
||||||
|
stub.locale = new Locale(attributes.getValue(XmlConstants.XML_ATTR_LOCALE));
|
||||||
|
stub.loginTime = ISO8601FormatFactory.getInstance()
|
||||||
|
.parseDate(attributes.getValue(XmlConstants.XML_ATTR_LOGIN_TIME));
|
||||||
|
stub.lastAccess = ISO8601FormatFactory.getInstance()
|
||||||
|
.parseDate(attributes.getValue(XmlConstants.XML_ATTR_LAST_ACCESS));
|
||||||
|
|
||||||
|
DBC.INTERIM.assertNotEmpty("sessionId missing on sessions data!", stub.sessionId);
|
||||||
|
DBC.INTERIM.assertNotEmpty("username missing on sessions data!", stub.username);
|
||||||
|
DBC.INTERIM.assertNotEmpty("authToken missing on sessions data!", stub.authToken);
|
||||||
|
|
||||||
|
this.stubs.add(stub);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new PrivilegeException("Unhandled tag " + qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CertificateStub {
|
||||||
|
private String sessionId;
|
||||||
|
private String username;
|
||||||
|
private String authToken;
|
||||||
|
private Locale locale;
|
||||||
|
private Date loginTime;
|
||||||
|
private Date lastAccess;
|
||||||
|
|
||||||
|
public String getSessionId() {
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthToken() {
|
||||||
|
return authToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locale getLocale() {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLoginTime() {
|
||||||
|
return loginTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getLastAccess() {
|
||||||
|
return lastAccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
// TODO write JavaDoc...
|
||||||
|
public interface ElementParser {
|
||||||
|
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException;
|
||||||
|
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException;
|
||||||
|
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException;
|
||||||
|
|
||||||
|
public void notifyChild(ElementParser child);
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
public abstract class ElementParserAdapter implements ElementParser {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
// empty implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
// empty implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
// empty implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyChild(ElementParser child) {
|
||||||
|
// empty implementation
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel;
|
||||||
|
import ch.eitchnet.privilege.policy.PrivilegePolicy;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PrivilegeConfigDomWriter {
|
||||||
|
|
||||||
|
private final PrivilegeContainerModel containerModel;
|
||||||
|
private final File configFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public PrivilegeConfigDomWriter(PrivilegeContainerModel containerModel, File configFile) {
|
||||||
|
this.containerModel = containerModel;
|
||||||
|
this.configFile = configFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void write() {
|
||||||
|
|
||||||
|
// create document root
|
||||||
|
Document doc = XmlHelper.createDocument();
|
||||||
|
Element rootElement = doc.createElement(XmlConstants.XML_ROOT_PRIVILEGE);
|
||||||
|
doc.appendChild(rootElement);
|
||||||
|
|
||||||
|
Element containerElement = doc.createElement(XmlConstants.XML_CONTAINER);
|
||||||
|
rootElement.appendChild(containerElement);
|
||||||
|
|
||||||
|
Element parameterElement;
|
||||||
|
Element parametersElement;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS);
|
||||||
|
containerElement.appendChild(parametersElement);
|
||||||
|
for (Entry<String, String> entry : this.containerModel.getParameterMap().entrySet()) {
|
||||||
|
parameterElement = doc.createElement(XmlConstants.XML_PARAMETER);
|
||||||
|
parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
|
||||||
|
parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
|
||||||
|
parametersElement.appendChild(parameterElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create EncryptionHandler
|
||||||
|
Element encryptionHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_ENCRYPTION);
|
||||||
|
containerElement.appendChild(encryptionHandlerElem);
|
||||||
|
encryptionHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS,
|
||||||
|
this.containerModel.getEncryptionHandlerClassName());
|
||||||
|
// Parameters
|
||||||
|
parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS);
|
||||||
|
encryptionHandlerElem.appendChild(parametersElement);
|
||||||
|
for (Entry<String, String> entry : this.containerModel.getEncryptionHandlerParameterMap().entrySet()) {
|
||||||
|
parameterElement = doc.createElement(XmlConstants.XML_PARAMETER);
|
||||||
|
parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
|
||||||
|
parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
|
||||||
|
parametersElement.appendChild(parameterElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create PersistenceHandler
|
||||||
|
Element persistenceHandlerElem = doc.createElement(XmlConstants.XML_HANDLER_PERSISTENCE);
|
||||||
|
containerElement.appendChild(persistenceHandlerElem);
|
||||||
|
persistenceHandlerElem.setAttribute(XmlConstants.XML_ATTR_CLASS,
|
||||||
|
this.containerModel.getPersistenceHandlerClassName());
|
||||||
|
// Parameters
|
||||||
|
parametersElement = doc.createElement(XmlConstants.XML_PARAMETERS);
|
||||||
|
persistenceHandlerElem.appendChild(parametersElement);
|
||||||
|
for (Entry<String, String> entry : this.containerModel.getPersistenceHandlerParameterMap().entrySet()) {
|
||||||
|
parameterElement = doc.createElement(XmlConstants.XML_PARAMETER);
|
||||||
|
parameterElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
|
||||||
|
parameterElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
|
||||||
|
parametersElement.appendChild(parameterElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Policies
|
||||||
|
Element policiesElem = doc.createElement(XmlConstants.XML_POLICIES);
|
||||||
|
rootElement.appendChild(policiesElem);
|
||||||
|
for (Entry<String, Class<PrivilegePolicy>> entry : this.containerModel.getPolicies().entrySet()) {
|
||||||
|
Element policyElem = doc.createElement(XmlConstants.XML_POLICY);
|
||||||
|
policyElem.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
|
||||||
|
policyElem.setAttribute(XmlConstants.XML_ATTR_CLASS, entry.getValue().getName());
|
||||||
|
policiesElem.appendChild(policyElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the container file to disk
|
||||||
|
XmlHelper.writeDocument(doc, this.configFile);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeConfigSaxReader extends DefaultHandler {
|
||||||
|
|
||||||
|
private Deque<ElementParser> buildersStack = new ArrayDeque<>();
|
||||||
|
|
||||||
|
private PrivilegeContainerModel containerModel;
|
||||||
|
|
||||||
|
public PrivilegeConfigSaxReader(PrivilegeContainerModel containerModel) {
|
||||||
|
this.containerModel = containerModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivilegeContainerModel getContainerModel() {
|
||||||
|
return this.containerModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
|
||||||
|
if (qName.equals(XmlConstants.XML_CONTAINER)) {
|
||||||
|
this.buildersStack.push(new ContainerParser());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PARAMETERS)) {
|
||||||
|
this.buildersStack.push(new ParametersParser());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_POLICIES)) {
|
||||||
|
this.buildersStack.push(new PoliciesParser());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().characters(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||||
|
|
||||||
|
ElementParser elementParser = null;
|
||||||
|
if (qName.equals(XmlConstants.XML_CONTAINER)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PARAMETERS)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
} else if (qName.equals(XmlConstants.XML_POLICIES)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty() && elementParser != null)
|
||||||
|
this.buildersStack.peek().notifyChild(elementParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ContainerParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
// <Container>
|
||||||
|
// <Parameters>
|
||||||
|
// <!-- parameters for the container itself -->
|
||||||
|
// <Parameter name="autoPersistOnPasswordChange" value="true" />
|
||||||
|
// </Parameters>
|
||||||
|
// <EncryptionHandler class="ch.eitchnet.privilege.handler.DefaultEncryptionHandler">
|
||||||
|
// <Parameters>
|
||||||
|
// <Parameter name="hashAlgorithm" value="SHA-256" />
|
||||||
|
// </Parameters>
|
||||||
|
// </EncryptionHandler>
|
||||||
|
// <PersistenceHandler class="ch.eitchnet.privilege.handler.XmlPersistenceHandler">
|
||||||
|
// <Parameters>
|
||||||
|
// <Parameter name="basePath" value="./target/test" />
|
||||||
|
// <Parameter name="modelXmlFile" value="PrivilegeModel.xml" />
|
||||||
|
// </Parameters>
|
||||||
|
// </PersistenceHandler>
|
||||||
|
// </Container>
|
||||||
|
|
||||||
|
private String currentElement;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
if (qName.equals(XmlConstants.XML_CONTAINER)) {
|
||||||
|
this.currentElement = qName;
|
||||||
|
} else if (qName.equals(XmlConstants.XML_HANDLER_ENCRYPTION)) {
|
||||||
|
this.currentElement = qName;
|
||||||
|
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
|
||||||
|
getContainerModel().setEncryptionHandlerClassName(className);
|
||||||
|
} else if (qName.equals(XmlConstants.XML_HANDLER_PERSISTENCE)) {
|
||||||
|
this.currentElement = qName;
|
||||||
|
String className = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
|
||||||
|
getContainerModel().setPersistenceHandlerClassName(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyChild(ElementParser child) {
|
||||||
|
if (!(child instanceof ParametersParser))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ParametersParser parametersChild = (ParametersParser) child;
|
||||||
|
|
||||||
|
if (this.currentElement.equals(XmlConstants.XML_CONTAINER)) {
|
||||||
|
getContainerModel().setParameterMap(parametersChild.getParameterMap());
|
||||||
|
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_ENCRYPTION)) {
|
||||||
|
getContainerModel().setEncryptionHandlerParameterMap(parametersChild.getParameterMap());
|
||||||
|
} else if (this.currentElement.equals(XmlConstants.XML_HANDLER_PERSISTENCE)) {
|
||||||
|
getContainerModel().setPersistenceHandlerParameterMap(parametersChild.getParameterMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParametersParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
// <Parameter name="autoPersistOnPasswordChange" value="true" />
|
||||||
|
|
||||||
|
private Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
if (qName.equals(XmlConstants.XML_PARAMETER)) {
|
||||||
|
String key = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||||
|
String value = attributes.getValue(XmlConstants.XML_ATTR_VALUE);
|
||||||
|
this.parameterMap.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the parameterMap
|
||||||
|
*/
|
||||||
|
public Map<String, String> getParameterMap() {
|
||||||
|
return this.parameterMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PoliciesParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
// <Policy name="DefaultPrivilege" class="ch.eitchnet.privilege.policy.DefaultPrivilege" />
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
if (qName.equals(XmlConstants.XML_POLICY)) {
|
||||||
|
String policyName = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||||
|
String policyClassName = attributes.getValue(XmlConstants.XML_ATTR_CLASS);
|
||||||
|
|
||||||
|
getContainerModel().addPolicy(policyName, policyClassName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeRolesDomWriter {
|
||||||
|
|
||||||
|
private List<Role> roles;
|
||||||
|
private File modelFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param users
|
||||||
|
* @param roles
|
||||||
|
* @param modelFile
|
||||||
|
*/
|
||||||
|
public PrivilegeRolesDomWriter(List<Role> roles, File modelFile) {
|
||||||
|
this.roles = roles;
|
||||||
|
this.modelFile = modelFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write() {
|
||||||
|
|
||||||
|
// create document root
|
||||||
|
Document doc = XmlHelper.createDocument();
|
||||||
|
Element rootElement = doc.createElement(XmlConstants.XML_ROLES);
|
||||||
|
doc.appendChild(rootElement);
|
||||||
|
|
||||||
|
this.roles.stream().sorted((r1, r2) -> r1.getName().compareTo(r2.getName())).forEach(role -> {
|
||||||
|
|
||||||
|
// create the role element
|
||||||
|
Element roleElement = doc.createElement(XmlConstants.XML_ROLE);
|
||||||
|
rootElement.appendChild(roleElement);
|
||||||
|
|
||||||
|
roleElement.setAttribute(XmlConstants.XML_ATTR_NAME, role.getName());
|
||||||
|
|
||||||
|
for (String privilegeName : role.getPrivilegeNames()) {
|
||||||
|
IPrivilege privilege = role.getPrivilege(privilegeName);
|
||||||
|
|
||||||
|
// create the privilege element
|
||||||
|
Element privilegeElement = doc.createElement(XmlConstants.XML_PRIVILEGE);
|
||||||
|
roleElement.appendChild(privilegeElement);
|
||||||
|
|
||||||
|
privilegeElement.setAttribute(XmlConstants.XML_ATTR_NAME, privilege.getName());
|
||||||
|
privilegeElement.setAttribute(XmlConstants.XML_ATTR_POLICY, privilege.getPolicy());
|
||||||
|
|
||||||
|
// add the all allowed element
|
||||||
|
if (privilege.isAllAllowed()) {
|
||||||
|
Element allAllowedElement = doc.createElement(XmlConstants.XML_ALL_ALLOWED);
|
||||||
|
allAllowedElement.setTextContent(Boolean.toString(privilege.isAllAllowed()));
|
||||||
|
privilegeElement.appendChild(allAllowedElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add all the deny values
|
||||||
|
for (String denyValue : privilege.getDenyList()) {
|
||||||
|
Element denyValueElement = doc.createElement(XmlConstants.XML_DENY);
|
||||||
|
denyValueElement.setTextContent(denyValue);
|
||||||
|
privilegeElement.appendChild(denyValueElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add all the allow values
|
||||||
|
for (String allowValue : privilege.getAllowList()) {
|
||||||
|
Element allowValueElement = doc.createElement(XmlConstants.XML_ALLOW);
|
||||||
|
allowValueElement.setTextContent(allowValue);
|
||||||
|
privilegeElement.appendChild(allowValueElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// write the container file to disk
|
||||||
|
XmlHelper.writeDocument(doc, this.modelFile);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeImpl;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeRolesSaxReader extends DefaultHandler {
|
||||||
|
|
||||||
|
protected static final Logger logger = LoggerFactory.getLogger(PrivilegeRolesSaxReader.class);
|
||||||
|
|
||||||
|
private Deque<ElementParser> buildersStack = new ArrayDeque<>();
|
||||||
|
|
||||||
|
private List<Role> roles;
|
||||||
|
|
||||||
|
public PrivilegeRolesSaxReader() {
|
||||||
|
this.roles = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Role> getRoles() {
|
||||||
|
return this.roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
|
||||||
|
if (qName.equals(XmlConstants.XML_ROLE)) {
|
||||||
|
this.buildersStack.push(new RoleParser());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||||
|
this.buildersStack.push(new PropertyParser());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().characters(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||||
|
|
||||||
|
ElementParser elementParser = null;
|
||||||
|
if (qName.equals(XmlConstants.XML_ROLE)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty() && elementParser != null)
|
||||||
|
this.buildersStack.peek().notifyChild(elementParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// <Role name="AppUser">
|
||||||
|
// <Privilege name="ch.eitchnet.privilege.test.model.TestRestrictable">
|
||||||
|
// <AllAllowed>true</AllAllowed>
|
||||||
|
// </Privilege>
|
||||||
|
// </Role>
|
||||||
|
// <Role name="system_admin_privileges">
|
||||||
|
// <Privilege name="ch.eitchnet.privilege.test.model.TestSystemUserAction">
|
||||||
|
// <AllAllowed>true</AllAllowed>
|
||||||
|
// </Privilege>
|
||||||
|
// <Privilege name="ch.eitchnet.privilege.test.model.TestSystemRestrictable">
|
||||||
|
// <AllAllowed>true</AllAllowed>
|
||||||
|
// </Privilege>
|
||||||
|
// </Role>
|
||||||
|
|
||||||
|
public class RoleParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
private StringBuilder text;
|
||||||
|
|
||||||
|
private String roleName;
|
||||||
|
private String privilegeName;
|
||||||
|
private String privilegePolicy;
|
||||||
|
private boolean allAllowed;
|
||||||
|
private Set<String> denyList;
|
||||||
|
private Set<String> allowList;
|
||||||
|
|
||||||
|
private Map<String, IPrivilege> privileges;
|
||||||
|
|
||||||
|
public RoleParser() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
this.privileges = new HashMap<>();
|
||||||
|
|
||||||
|
this.text = null;
|
||||||
|
|
||||||
|
this.roleName = null;
|
||||||
|
this.privilegeName = null;
|
||||||
|
this.privilegePolicy = null;
|
||||||
|
this.allAllowed = false;
|
||||||
|
this.denyList = new HashSet<>();
|
||||||
|
this.allowList = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
|
||||||
|
this.text = new StringBuilder();
|
||||||
|
|
||||||
|
if (qName.equals(XmlConstants.XML_ROLE)) {
|
||||||
|
this.roleName = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PRIVILEGE)) {
|
||||||
|
this.privilegeName = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||||
|
this.privilegePolicy = attributes.getValue(XmlConstants.XML_ATTR_POLICY);
|
||||||
|
} else if (qName.equals(XmlConstants.XML_ALLOW) || qName.equals(XmlConstants.XML_DENY)
|
||||||
|
|| qName.equals(XmlConstants.XML_ALL_ALLOWED)) {
|
||||||
|
// no-op
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
if (this.text != null)
|
||||||
|
this.text.append(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
|
||||||
|
if (qName.equals(XmlConstants.XML_ALL_ALLOWED)) {
|
||||||
|
this.allAllowed = StringHelper.parseBoolean(this.text.toString().trim());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_ALLOW)) {
|
||||||
|
this.allowList.add(this.text.toString().trim());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_DENY)) {
|
||||||
|
this.denyList.add(this.text.toString().trim());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PRIVILEGE)) {
|
||||||
|
|
||||||
|
IPrivilege privilege = new PrivilegeImpl(this.privilegeName, this.privilegePolicy, this.allAllowed,
|
||||||
|
this.denyList, this.allowList);
|
||||||
|
this.privileges.put(this.privilegeName, privilege);
|
||||||
|
|
||||||
|
this.privilegeName = null;
|
||||||
|
this.privilegePolicy = null;
|
||||||
|
this.allAllowed = false;
|
||||||
|
this.denyList = new HashSet<>();
|
||||||
|
this.allowList = new HashSet<>();
|
||||||
|
|
||||||
|
} else if (qName.equals(XmlConstants.XML_ROLE)) {
|
||||||
|
|
||||||
|
Role role = new Role(this.roleName, this.privileges);
|
||||||
|
|
||||||
|
getRoles().add(role);
|
||||||
|
logger.info(MessageFormat.format("New Role: {0}", role)); //$NON-NLS-1$
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PropertyParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
// <Property name="organizationalUnit" value="Development" />
|
||||||
|
|
||||||
|
public Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
if (qName.equals(XmlConstants.XML_PROPERTY)) {
|
||||||
|
String key = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||||
|
String value = attributes.getValue(XmlConstants.XML_ATTR_VALUE);
|
||||||
|
this.parameterMap.put(key, value);
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||||
|
// NO-OP
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getParameterMap() {
|
||||||
|
return this.parameterMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeUsersDomWriter {
|
||||||
|
|
||||||
|
private List<User> users;
|
||||||
|
private File modelFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param users
|
||||||
|
* @param modelFile
|
||||||
|
*/
|
||||||
|
public PrivilegeUsersDomWriter(List<User> users, File modelFile) {
|
||||||
|
this.users = users;
|
||||||
|
this.modelFile = modelFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write() {
|
||||||
|
|
||||||
|
// create document root
|
||||||
|
Document doc = XmlHelper.createDocument();
|
||||||
|
Element rootElement = doc.createElement(XmlConstants.XML_USERS);
|
||||||
|
doc.appendChild(rootElement);
|
||||||
|
|
||||||
|
this.users.stream().sorted((u1, u2) -> u1.getUserId().compareTo(u2.getUserId())).forEach(user -> {
|
||||||
|
|
||||||
|
// create the user element
|
||||||
|
Element userElement = doc.createElement(XmlConstants.XML_USER);
|
||||||
|
rootElement.appendChild(userElement);
|
||||||
|
|
||||||
|
userElement.setAttribute(XmlConstants.XML_ATTR_USER_ID, user.getUserId());
|
||||||
|
userElement.setAttribute(XmlConstants.XML_ATTR_USERNAME, user.getUsername());
|
||||||
|
if (StringHelper.isNotEmpty(user.getPassword()))
|
||||||
|
userElement.setAttribute(XmlConstants.XML_ATTR_PASSWORD, user.getPassword());
|
||||||
|
|
||||||
|
// add first name element
|
||||||
|
if (StringHelper.isNotEmpty(user.getFirstname())) {
|
||||||
|
Element firstnameElement = doc.createElement(XmlConstants.XML_FIRSTNAME);
|
||||||
|
firstnameElement.setTextContent(user.getFirstname());
|
||||||
|
userElement.appendChild(firstnameElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add last name element
|
||||||
|
if (StringHelper.isNotEmpty(user.getLastname())) {
|
||||||
|
Element lastnameElement = doc.createElement(XmlConstants.XML_LASTNAME);
|
||||||
|
lastnameElement.setTextContent(user.getLastname());
|
||||||
|
userElement.appendChild(lastnameElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add state element
|
||||||
|
Element stateElement = doc.createElement(XmlConstants.XML_STATE);
|
||||||
|
stateElement.setTextContent(user.getUserState().toString());
|
||||||
|
userElement.appendChild(stateElement);
|
||||||
|
|
||||||
|
// add locale element
|
||||||
|
Element localeElement = doc.createElement(XmlConstants.XML_LOCALE);
|
||||||
|
localeElement.setTextContent(user.getLocale().toString());
|
||||||
|
userElement.appendChild(localeElement);
|
||||||
|
|
||||||
|
// add all the role elements
|
||||||
|
Element rolesElement = doc.createElement(XmlConstants.XML_ROLES);
|
||||||
|
userElement.appendChild(rolesElement);
|
||||||
|
for (String roleName : user.getRoles()) {
|
||||||
|
Element roleElement = doc.createElement(XmlConstants.XML_ROLE);
|
||||||
|
roleElement.setTextContent(roleName);
|
||||||
|
rolesElement.appendChild(roleElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the parameters
|
||||||
|
if (!user.getProperties().isEmpty()) {
|
||||||
|
Element parametersElement = doc.createElement(XmlConstants.XML_PROPERTIES);
|
||||||
|
userElement.appendChild(parametersElement);
|
||||||
|
for (Entry<String, String> entry : user.getProperties().entrySet()) {
|
||||||
|
Element paramElement = doc.createElement(XmlConstants.XML_PROPERTY);
|
||||||
|
paramElement.setAttribute(XmlConstants.XML_ATTR_NAME, entry.getKey());
|
||||||
|
paramElement.setAttribute(XmlConstants.XML_ATTR_VALUE, entry.getValue());
|
||||||
|
parametersElement.appendChild(paramElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// write the container file to disk
|
||||||
|
XmlHelper.writeDocument(doc, this.modelFile);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.xml;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.helper.XmlConstants;
|
||||||
|
import ch.eitchnet.privilege.model.UserState;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeUsersSaxReader extends DefaultHandler {
|
||||||
|
|
||||||
|
protected static final Logger logger = LoggerFactory.getLogger(PrivilegeUsersSaxReader.class);
|
||||||
|
|
||||||
|
private Deque<ElementParser> buildersStack = new ArrayDeque<>();
|
||||||
|
|
||||||
|
private List<User> users;
|
||||||
|
|
||||||
|
public PrivilegeUsersSaxReader() {
|
||||||
|
this.users = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the users
|
||||||
|
*/
|
||||||
|
public List<User> getUsers() {
|
||||||
|
return this.users;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
if (qName.equals(XmlConstants.XML_USER)) {
|
||||||
|
this.buildersStack.push(new UserParser());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||||
|
this.buildersStack.push(new PropertyParser());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().characters(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty())
|
||||||
|
this.buildersStack.peek().endElement(uri, localName, qName);
|
||||||
|
|
||||||
|
ElementParser elementParser = null;
|
||||||
|
if (qName.equals(XmlConstants.XML_USER)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||||
|
elementParser = this.buildersStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.buildersStack.isEmpty() && elementParser != null)
|
||||||
|
this.buildersStack.peek().notifyChild(elementParser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// <User userId="1" username="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918">
|
||||||
|
// <Firstname>Application</Firstname>
|
||||||
|
// <Lastname>Administrator</Lastname>
|
||||||
|
// <State>ENABLED</State>
|
||||||
|
// <Locale>en_GB</Locale>
|
||||||
|
// <Roles>
|
||||||
|
// <Role>PrivilegeAdmin</Role>
|
||||||
|
// <Role>AppUser</Role>
|
||||||
|
// </Roles>
|
||||||
|
// <Properties>
|
||||||
|
// <Property name="organization" value="eitchnet.ch" />
|
||||||
|
// <Property name="organizationalUnit" value="Development" />
|
||||||
|
// </Properties>
|
||||||
|
// </User>
|
||||||
|
|
||||||
|
public class UserParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
StringBuilder text;
|
||||||
|
|
||||||
|
String userId;
|
||||||
|
String username;
|
||||||
|
String password;
|
||||||
|
String firstName;
|
||||||
|
String lastname;
|
||||||
|
UserState userState;
|
||||||
|
Locale locale;
|
||||||
|
Set<String> userRoles;
|
||||||
|
Map<String, String> parameters;
|
||||||
|
|
||||||
|
public UserParser() {
|
||||||
|
this.userRoles = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
|
||||||
|
this.text = new StringBuilder();
|
||||||
|
|
||||||
|
if (qName.equals(XmlConstants.XML_USER)) {
|
||||||
|
this.userId = attributes.getValue(XmlConstants.XML_ATTR_USER_ID);
|
||||||
|
this.username = attributes.getValue(XmlConstants.XML_ATTR_USERNAME);
|
||||||
|
this.password = attributes.getValue(XmlConstants.XML_ATTR_PASSWORD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
this.text.append(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
|
||||||
|
if (qName.equals(XmlConstants.XML_FIRSTNAME)) {
|
||||||
|
this.firstName = this.text.toString().trim();
|
||||||
|
} else if (qName.equals(XmlConstants.XML_LASTNAME)) {
|
||||||
|
this.lastname = this.text.toString().trim();
|
||||||
|
} else if (qName.equals(XmlConstants.XML_STATE)) {
|
||||||
|
this.userState = UserState.valueOf(this.text.toString().trim());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_LOCALE)) {
|
||||||
|
this.locale = new Locale(this.text.toString().trim());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_ROLE)) {
|
||||||
|
this.userRoles.add(this.text.toString().trim());
|
||||||
|
} else if (qName.equals(XmlConstants.XML_ROLES)) {
|
||||||
|
// NO-OP
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PARAMETER)) {
|
||||||
|
// NO-OP
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PARAMETERS)) {
|
||||||
|
// NO-OP
|
||||||
|
} else if (qName.equals(XmlConstants.XML_USER)) {
|
||||||
|
|
||||||
|
User user = new User(this.userId, this.username, this.password, this.firstName, this.lastname,
|
||||||
|
this.userState, this.userRoles, this.locale, this.parameters);
|
||||||
|
logger.info(MessageFormat.format("New User: {0}", user)); //$NON-NLS-1$
|
||||||
|
getUsers().add(user);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyChild(ElementParser child) {
|
||||||
|
if (child instanceof PropertyParser) {
|
||||||
|
this.parameters = ((PropertyParser) child).parameterMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PropertyParser extends ElementParserAdapter {
|
||||||
|
|
||||||
|
// <Property name="organizationalUnit" value="Development" />
|
||||||
|
|
||||||
|
public Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes)
|
||||||
|
throws SAXException {
|
||||||
|
if (qName.equals(XmlConstants.XML_PROPERTY)) {
|
||||||
|
String key = attributes.getValue(XmlConstants.XML_ATTR_NAME);
|
||||||
|
String value = attributes.getValue(XmlConstants.XML_ATTR_VALUE);
|
||||||
|
this.parameterMap.put(key, value);
|
||||||
|
} else if (qName.equals(XmlConstants.XML_PROPERTIES)) {
|
||||||
|
// NO-OP
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unhandled tag " + qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getParameterMap() {
|
||||||
|
return this.parameterMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.eitchnet.ch/dev/privilege/Privilege"
|
||||||
|
xmlns:pr="http://www.eitchnet.ch/dev/privilege/Privilege" elementFormDefault="qualified">
|
||||||
|
|
||||||
|
<element name="Privilege">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
|
||||||
|
Licensed 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.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element name="Container" minOccurs="1" maxOccurs="1">
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element name="Parameters" type="pr:Parameters" minOccurs="1" maxOccurs="1" />
|
||||||
|
<element name="EncryptionHandler" type="pr:EncryptionHandler" minOccurs="1" maxOccurs="1" />
|
||||||
|
<element name="PersistenceHandler" type="pr:PersistenceHandler" minOccurs="1" maxOccurs="1" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
<element name="Policies" type="pr:Policies" minOccurs="1" maxOccurs="1" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<complexType name="Parameters">
|
||||||
|
<sequence>
|
||||||
|
<element name="Parameter" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<complexType>
|
||||||
|
<simpleContent>
|
||||||
|
<extension base="string">
|
||||||
|
<attribute type="string" name="name" use="required" />
|
||||||
|
<attribute type="string" name="value" use="required" />
|
||||||
|
</extension>
|
||||||
|
</simpleContent>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
<complexType name="EncryptionHandler">
|
||||||
|
<sequence>
|
||||||
|
<element name="Parameters" type="pr:Parameters" minOccurs="0" maxOccurs="1" />
|
||||||
|
</sequence>
|
||||||
|
<attribute type="string" name="class" use="required" />
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
<complexType name="PersistenceHandler">
|
||||||
|
<sequence>
|
||||||
|
<element name="Parameters" type="pr:Parameters" minOccurs="0" maxOccurs="1" />
|
||||||
|
</sequence>
|
||||||
|
<attribute type="string" name="class" use="required" />
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
<complexType name="Policies">
|
||||||
|
<sequence>
|
||||||
|
<element name="Policy" minOccurs="0" maxOccurs="1">
|
||||||
|
<complexType>
|
||||||
|
<simpleContent>
|
||||||
|
<extension base="string">
|
||||||
|
<attribute type="string" name="name" use="required" />
|
||||||
|
<attribute type="string" name="class" use="required" />
|
||||||
|
</extension>
|
||||||
|
</simpleContent>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,14 @@
|
||||||
|
Privilege.accessdenied.noprivilege=User {0} does not have the privilege {1} needed for Restrictable {2}
|
||||||
|
Privilege.illegalArgument.nonstring=\ {0} has returned a non-string privilege value\!
|
||||||
|
Privilege.illegalArgument.nonrole=\ {0} did not return a Role privilege value\!
|
||||||
|
Privilege.illegalArgument.noncertificate=\ {0} did not return a Certificate privilege value\!
|
||||||
|
Privilege.illegalArgument.nonuser=\ {0} did not return a User privilege value\!
|
||||||
|
Privilege.illegalArgument.privilegeNameMismatch=The passed privilege has the name {0} but the restrictable is referencing privilege {1}
|
||||||
|
Privilege.illegalArgument.nontuple=\ {0} did not return a Tuple privilege value\!
|
||||||
|
Privilege.privilegeNameEmpty=The PrivilegeName for the Restrictable is null or empty: {0}
|
||||||
|
Privilege.privilegeNull=Privilege may not be null\!
|
||||||
|
Privilege.restrictableNull=Restrictable may not be null\!
|
||||||
|
Privilege.noprivilege=No Privilege exists with name {0}
|
||||||
|
Privilege.noprivilege.user=User {0} does not have the privilege {1}
|
||||||
|
Privilege.roleAccessPrivilege.unknownPrivilege=Unhandled privilege {0} for policy {1}
|
||||||
|
Privilege.userAccessPrivilege.unknownPrivilege=Unhandled privilege {0} for policy {1}
|
|
@ -0,0 +1,98 @@
|
||||||
|
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.eitchnet.ch/dev/privilege/PrivilegeModel"
|
||||||
|
xmlns:pr="http://www.eitchnet.ch/dev/privilege/PrivilegeModel" elementFormDefault="qualified">
|
||||||
|
|
||||||
|
<element name="UsersAndRoles">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
|
||||||
|
Licensed 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.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element name="Users">
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element name="User" type="pr:User" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="Roles">
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element name="Role" type="pr:Role" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<complexType name="User">
|
||||||
|
<sequence>
|
||||||
|
|
||||||
|
<element type="string" name="Firstname" minOccurs="1" maxOccurs="1" />
|
||||||
|
<element type="string" name="Lastname" minOccurs="1" maxOccurs="1" />
|
||||||
|
<element type="string" name="State" minOccurs="1" maxOccurs="1" />
|
||||||
|
<element type="string" name="Locale" minOccurs="0" maxOccurs="1" />
|
||||||
|
|
||||||
|
<element name="Roles" minOccurs="1" maxOccurs="1">
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element type="string" name="Role" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="Properties" type="pr:Properties" minOccurs="0" maxOccurs="1" />
|
||||||
|
</sequence>
|
||||||
|
<attribute type="long" name="userId" use="required" />
|
||||||
|
<attribute type="string" name="username" use="required" />
|
||||||
|
<attribute type="string" name="password" use="required" />
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
<complexType name="Properties">
|
||||||
|
<sequence>
|
||||||
|
<element name="Property" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<complexType>
|
||||||
|
<simpleContent>
|
||||||
|
<extension base="string">
|
||||||
|
<attribute type="string" name="name" use="required" />
|
||||||
|
<attribute type="string" name="value" use="required" />
|
||||||
|
</extension>
|
||||||
|
</simpleContent>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
<complexType name="Role" mixed="true">
|
||||||
|
<sequence>
|
||||||
|
<element name="Privilege" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<complexType>
|
||||||
|
<sequence>
|
||||||
|
<element type="string" name="AllAllowed" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<element type="string" name="Allow" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
<element type="string" name="Deny" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
</sequence>
|
||||||
|
<attribute type="string" name="name" use="required" />
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
</sequence>
|
||||||
|
<attribute type="string" name="name" use="required" />
|
||||||
|
</complexType>
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,116 @@
|
||||||
|
package ch.eitchnet.privilege.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.helper.PrivilegeInitializationHelper;
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
import ch.eitchnet.utils.helper.FileHelper;
|
||||||
|
|
||||||
|
public class AbstractPrivilegeTest {
|
||||||
|
|
||||||
|
protected static final Logger logger = LoggerFactory.getLogger(AbstractPrivilegeTest.class);
|
||||||
|
|
||||||
|
protected PrivilegeHandler privilegeHandler;
|
||||||
|
protected PrivilegeContext ctx;
|
||||||
|
|
||||||
|
protected void login(String username, byte[] password) {
|
||||||
|
Certificate certificate = privilegeHandler.authenticate(username, password);
|
||||||
|
assertTrue("Certificate is null!", certificate != null);
|
||||||
|
PrivilegeContext privilegeContext = privilegeHandler.getPrivilegeContext(certificate);
|
||||||
|
this.ctx = privilegeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void logout() {
|
||||||
|
if (this.ctx != null) {
|
||||||
|
try {
|
||||||
|
PrivilegeContext privilegeContext = this.ctx;
|
||||||
|
this.ctx = null;
|
||||||
|
privilegeHandler.invalidateSession(privilegeContext.getCertificate());
|
||||||
|
} catch (PrivilegeException e) {
|
||||||
|
String msg = "There is no PrivilegeContext currently bound to the ThreadLocal!";
|
||||||
|
if (!e.getMessage().equals(msg))
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void prepareConfigs(String dst, String configFilename, String usersFilename,
|
||||||
|
String rolesFilename) {
|
||||||
|
try {
|
||||||
|
String pwd = System.getProperty("user.dir");
|
||||||
|
|
||||||
|
File configPath = new File(pwd, "config");
|
||||||
|
|
||||||
|
File privilegeConfigFile = new File(configPath, configFilename);
|
||||||
|
File privilegeUsersFile = new File(configPath, usersFilename);
|
||||||
|
File privilegeRolesFile = new File(configPath, rolesFilename);
|
||||||
|
|
||||||
|
File targetPath = new File(pwd, "target/" + dst);
|
||||||
|
if (!targetPath.mkdirs())
|
||||||
|
throw new RuntimeException("Could not create parent " + targetPath);
|
||||||
|
|
||||||
|
File dstConfig = new File(targetPath, configFilename);
|
||||||
|
File dstUsers = new File(targetPath, usersFilename);
|
||||||
|
File dstRoles = new File(targetPath, rolesFilename);
|
||||||
|
|
||||||
|
// write config
|
||||||
|
String config = new String(Files.readAllBytes(privilegeConfigFile.toPath()), "UTF-8");
|
||||||
|
config = config.replace("${target}", dst);
|
||||||
|
Files.write(dstConfig.toPath(), config.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
// copy model
|
||||||
|
Files.copy(privilegeUsersFile.toPath(), dstUsers.toPath());
|
||||||
|
Files.copy(privilegeRolesFile.toPath(), dstRoles.toPath());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Initialization failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void removeConfigs(String dst) {
|
||||||
|
try {
|
||||||
|
String pwd = System.getProperty("user.dir");
|
||||||
|
File targetPath = new File(pwd, "target");
|
||||||
|
targetPath = new File(targetPath, dst);
|
||||||
|
if (targetPath.exists() && !FileHelper.deleteFile(targetPath, true)) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Tmp configuration still exists and can not be deleted at " + targetPath.getAbsolutePath());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Initialization failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static File getPrivilegeConfigFile(String dst, String configFilename) {
|
||||||
|
try {
|
||||||
|
String pwd = System.getProperty("user.dir");
|
||||||
|
File targetPath = new File(pwd, "target");
|
||||||
|
targetPath = new File(targetPath, dst);
|
||||||
|
return new File(targetPath, configFilename);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Initialization failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initialize(String dst, String configFilename) {
|
||||||
|
try {
|
||||||
|
File privilegeConfigFile = getPrivilegeConfigFile(dst, configFilename);
|
||||||
|
this.privilegeHandler = PrivilegeInitializationHelper.initializeFromXml(privilegeConfigFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Initialization failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package ch.eitchnet.privilege.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class PersistSessionsTest extends AbstractPrivilegeTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws Exception {
|
||||||
|
removeConfigs(PersistSessionsTest.class.getSimpleName());
|
||||||
|
prepareConfigs(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml", "PrivilegeUsers.xml",
|
||||||
|
"PrivilegeRoles.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void destroy() throws Exception {
|
||||||
|
removeConfigs(PersistSessionsTest.class.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
initialize(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPersistAndReloadSessions() {
|
||||||
|
|
||||||
|
// assert no sessions file
|
||||||
|
File sessionsFile = new File("target/PersistSessionsTest/sessions.dat");
|
||||||
|
assertFalse("Sessions File should no yet exist", sessionsFile.exists());
|
||||||
|
|
||||||
|
// login and assert sessions file was written
|
||||||
|
login("admin", "admin".getBytes());
|
||||||
|
this.privilegeHandler.isCertificateValid(ctx.getCertificate());
|
||||||
|
assertTrue("Sessions File should have been created!", sessionsFile.isFile());
|
||||||
|
|
||||||
|
// re-initialize and assert still logged in
|
||||||
|
initialize(PersistSessionsTest.class.getSimpleName(), "PrivilegeConfig.xml");
|
||||||
|
this.privilegeHandler.isCertificateValid(ctx.getCertificate());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class PrivilegeConflictMergeTest extends AbstractPrivilegeTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws Exception {
|
||||||
|
removeConfigs(PrivilegeConflictMergeTest.class.getSimpleName());
|
||||||
|
prepareConfigs(PrivilegeConflictMergeTest.class.getSimpleName(), "PrivilegeConfigMerge.xml",
|
||||||
|
"PrivilegeUsersMerge.xml", "PrivilegeRolesMerge.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void destroy() throws Exception {
|
||||||
|
removeConfigs(PrivilegeConflictMergeTest.class.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
initialize(PrivilegeConflictMergeTest.class.getSimpleName(), "PrivilegeConfigMerge.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMergePrivileges1() {
|
||||||
|
try {
|
||||||
|
login("userA", "admin".getBytes());
|
||||||
|
IPrivilege privilege = this.ctx.getPrivilege("Foo");
|
||||||
|
assertTrue(privilege.isAllAllowed());
|
||||||
|
assertTrue(privilege.getAllowList().isEmpty());
|
||||||
|
assertTrue(privilege.getDenyList().isEmpty());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMergePrivileges2() {
|
||||||
|
try {
|
||||||
|
login("userB", "admin".getBytes());
|
||||||
|
IPrivilege privilege = this.ctx.getPrivilege("Bar");
|
||||||
|
assertFalse(privilege.isAllAllowed());
|
||||||
|
assertEquals(2, privilege.getAllowList().size());
|
||||||
|
assertEquals(2, privilege.getDenyList().size());
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,755 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.base.AccessDeniedException;
|
||||||
|
import ch.eitchnet.privilege.base.PrivilegeException;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.i18n.PrivilegeMessages;
|
||||||
|
import ch.eitchnet.privilege.model.Certificate;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeRep;
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
import ch.eitchnet.privilege.model.RoleRep;
|
||||||
|
import ch.eitchnet.privilege.model.UserRep;
|
||||||
|
import ch.eitchnet.privilege.model.UserState;
|
||||||
|
import ch.eitchnet.privilege.test.model.TestRestrictable;
|
||||||
|
import ch.eitchnet.privilege.test.model.TestSystemUserAction;
|
||||||
|
import ch.eitchnet.privilege.test.model.TestSystemUserActionDeny;
|
||||||
|
import ch.eitchnet.utils.helper.ArraysHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JUnit for performing Privilege tests. This JUnit is by no means complete, but checks the bare minimum.br />
|
||||||
|
*
|
||||||
|
* TODO add more tests, especially with deny and allow lists
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class PrivilegeTest extends AbstractPrivilegeTest {
|
||||||
|
|
||||||
|
private static final String ROLE_PRIVILEGE_ADMIN = "PrivilegeAdmin";
|
||||||
|
private static final String PRIVILEGE_USER_ACCESS = "UserAccessPrivilege";
|
||||||
|
private static final String ADMIN = "admin";
|
||||||
|
private static final byte[] PASS_ADMIN = "admin".getBytes();
|
||||||
|
private static final String BOB = "bob";
|
||||||
|
private static final String TED = "ted";
|
||||||
|
private static final String SYSTEM_USER_ADMIN = "system_admin";
|
||||||
|
private static final String SYSTEM_USER_ADMIN2 = "system_admin2";
|
||||||
|
private static final byte[] PASS_BOB = "admin1".getBytes();
|
||||||
|
private static final String ROLE_APP_USER = "AppUser";
|
||||||
|
private static final String ROLE_MY = "MyRole";
|
||||||
|
private static final String ROLE_MY2 = "MyRole2";
|
||||||
|
private static final String ROLE_CHANGE_PW = "changePw";
|
||||||
|
private static final String ROLE_TEMP = "temp";
|
||||||
|
private static final String ROLE_USER = "user";
|
||||||
|
private static final byte[] PASS_DEF = "def".getBytes();
|
||||||
|
private static final byte[] PASS_BAD = "123".getBytes();
|
||||||
|
private static final byte[] PASS_TED = "12345".getBytes();
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PrivilegeTest.class);
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws Exception {
|
||||||
|
removeConfigs(PrivilegeTest.class.getSimpleName());
|
||||||
|
prepareConfigs(PrivilegeTest.class.getSimpleName(), "PrivilegeConfig.xml", "PrivilegeUsers.xml",
|
||||||
|
"PrivilegeRoles.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void destroy() throws Exception {
|
||||||
|
removeConfigs(PrivilegeTest.class.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
initialize(PrivilegeTest.class.getSimpleName(), "PrivilegeConfig.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthenticationOk() throws Exception {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFailAuthenticationNOk() throws Exception {
|
||||||
|
this.exception.expect(AccessDeniedException.class);
|
||||||
|
this.exception.expectMessage("blabla");
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_BAD));
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFailAuthenticationPWNull() throws Exception {
|
||||||
|
this.exception.expect(PrivilegeException.class);
|
||||||
|
this.exception.expectMessage("blabla");
|
||||||
|
try {
|
||||||
|
login(ADMIN, null);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddRoleTemp() throws Exception {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
RoleRep roleRep = new RoleRep(ROLE_TEMP, new ArrayList<>());
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRole(certificate, roleRep);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPerformRestrictableAsAdmin() throws Exception {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
// see if admin can perform restrictable
|
||||||
|
Restrictable restrictable = new TestRestrictable();
|
||||||
|
this.ctx.validateAction(restrictable);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if an action can be performed as a system user
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testPerformSystemRestrictable() throws Exception {
|
||||||
|
|
||||||
|
// create the action to be performed as a system user and then perform the action
|
||||||
|
TestSystemUserAction action = new TestSystemUserAction();
|
||||||
|
privilegeHandler.runAsSystem(SYSTEM_USER_ADMIN, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the system user can not perform a valid action, but illegal privilege
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testPerformSystemRestrictableFailPrivilege() throws Exception {
|
||||||
|
this.exception.expect(PrivilegeException.class);
|
||||||
|
this.exception.expectMessage(
|
||||||
|
"User system_admin does not have the privilege ch.eitchnet.privilege.handler.SystemUserAction");
|
||||||
|
try {
|
||||||
|
// create the action to be performed as a system user
|
||||||
|
TestSystemUserActionDeny action = new TestSystemUserActionDeny();
|
||||||
|
|
||||||
|
// and then perform the action
|
||||||
|
privilegeHandler.runAsSystem(SYSTEM_USER_ADMIN, action);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the system user can not perform a valid action, but illegal privilege
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testPerformSystemRestrictableFailNoAdditionalPrivilege() throws Exception {
|
||||||
|
this.exception.expect(PrivilegeException.class);
|
||||||
|
this.exception.expectMessage(
|
||||||
|
"User system_admin2 does not have the privilege ch.eitchnet.privilege.handler.SystemUserAction needed for Restrictable ch.eitchnet.privilege.test.model.TestSystemUserActionDeny");
|
||||||
|
try {
|
||||||
|
// create the action to be performed as a system user
|
||||||
|
TestSystemUserActionDeny action = new TestSystemUserActionDeny();
|
||||||
|
|
||||||
|
// and then perform the action
|
||||||
|
privilegeHandler.runAsSystem(SYSTEM_USER_ADMIN2, action);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System user may not login
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testLoginSystemUser() throws Exception {
|
||||||
|
this.exception.expect(AccessDeniedException.class);
|
||||||
|
this.exception.expectMessage("User system_admin is a system user and may not login!");
|
||||||
|
try {
|
||||||
|
login(SYSTEM_USER_ADMIN, SYSTEM_USER_ADMIN.getBytes());
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrivilegeContext() {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Restrictable restrictable = new TestRestrictable();
|
||||||
|
this.ctx.validateAction(restrictable);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldUpdateAdmin() {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
// validate name is not yet set
|
||||||
|
UserRep user = privilegeHandler.getUser(certificate, ADMIN);
|
||||||
|
assertNotEquals("The", user.getFirstname());
|
||||||
|
assertNotEquals("Admin", user.getLastname());
|
||||||
|
|
||||||
|
// let's add a new user bob
|
||||||
|
UserRep userRep = new UserRep(null, ADMIN, "The", "Admin", null, null, null, null);
|
||||||
|
privilegeHandler.updateUser(certificate, userRep);
|
||||||
|
|
||||||
|
user = privilegeHandler.getUser(certificate, ADMIN);
|
||||||
|
assertEquals("The", user.getFirstname());
|
||||||
|
assertEquals("Admin", user.getLastname());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailUpdateInexistantUser() {
|
||||||
|
exception.expect(PrivilegeException.class);
|
||||||
|
exception.expectMessage("User bob does not exist");
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
// let's add a new user bob
|
||||||
|
UserRep userRep = new UserRep(null, BOB, null, null, null, null, null, null);
|
||||||
|
privilegeHandler.updateUser(certificate, userRep);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailUpdateAdminNoChanges() {
|
||||||
|
exception.expect(PrivilegeException.class);
|
||||||
|
exception.expectMessage("All updateable fields are empty for update of user admin");
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
// let's add a new user bob
|
||||||
|
UserRep userRep = new UserRep(null, ADMIN, null, null, null, null, null, null);
|
||||||
|
privilegeHandler.updateUser(certificate, userRep);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldQueryUsers() {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
UserRep selectorRep = new UserRep(null, ADMIN, null, null, null, null, null, null);
|
||||||
|
List<UserRep> users = privilegeHandler.queryUsers(certificate, selectorRep);
|
||||||
|
assertEquals(1, users.size());
|
||||||
|
assertEquals(ADMIN, users.get(0).getUsername());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldQueryUsersByRoles() {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
UserRep selectorRep = new UserRep(null, null, null, null, null,
|
||||||
|
new HashSet<>(Arrays.asList("PrivilegeAdmin")), null, null);
|
||||||
|
List<UserRep> users = privilegeHandler.queryUsers(certificate, selectorRep);
|
||||||
|
assertEquals(1, users.size());
|
||||||
|
assertEquals(ADMIN, users.get(0).getUsername());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldQueryUsersByRoles2() {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
UserRep selectorRep = new UserRep(null, null, null, null, null, new HashSet<>(Arrays.asList(ROLE_TEMP)),
|
||||||
|
null, null);
|
||||||
|
List<UserRep> users = privilegeHandler.queryUsers(certificate, selectorRep);
|
||||||
|
assertEquals(0, users.size());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldDetectPrivilegeConflict1() {
|
||||||
|
exception.expect(PrivilegeException.class);
|
||||||
|
exception.expectMessage("User admin has conflicts for privilege ");
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
PrivilegeRep privilegeRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_ACTION, "DefaultPrivilege", true,
|
||||||
|
Collections.emptySet(), Collections.emptySet());
|
||||||
|
privilegeHandler.addOrReplacePrivilegeOnRole(certificate, ROLE_APP_USER, privilegeRep);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldDetectPrivilegeConflict2() {
|
||||||
|
exception.expect(PrivilegeException.class);
|
||||||
|
exception.expectMessage("User admin has conflicts for privilege ");
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRoleToUser(certificate, ADMIN, ROLE_MY);
|
||||||
|
privilegeHandler.addRoleToUser(certificate, ADMIN, ROLE_MY2);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test performs multiple tests which are dependent on each other as the following is done:
|
||||||
|
* <ul>
|
||||||
|
* <li>add user bob</li>
|
||||||
|
* <li>fail to auth as bob as user is not enabled</li>
|
||||||
|
* <li>enable bob</li>
|
||||||
|
* <li>fail to auth as bot as bob has no role</li>
|
||||||
|
* <li>add role user to bob</li>
|
||||||
|
* <li>auth as bob</li>
|
||||||
|
* <li>fail to add user ted as bob as bob is not admin</li>
|
||||||
|
* <li>add admin role to bob</li>
|
||||||
|
* <li>add user ted as bob</li>
|
||||||
|
* <li>fail to auth as ted as ted has no password</li>
|
||||||
|
* <li>set ted's password as bob</li>
|
||||||
|
* <li>ted changes own password</li>
|
||||||
|
* <li>auth as ted</li>
|
||||||
|
* <li>fail to perform restrictable as bob as no app role</li>
|
||||||
|
* <li>add app role to bob</li>
|
||||||
|
* <li>perform restrictable as bob</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testUserStory() throws Exception {
|
||||||
|
|
||||||
|
addBobAsAdmin();
|
||||||
|
failAuthAsBobNotEnabled();
|
||||||
|
enableBob();
|
||||||
|
addRoleUser();
|
||||||
|
addRoleUserToBob();
|
||||||
|
authAsBob();
|
||||||
|
failAddTedAsBobNotAdmin();
|
||||||
|
addRoleAdminToBob();
|
||||||
|
addTedAsBob();
|
||||||
|
failAuthAsTedNoPass();
|
||||||
|
setPassForTedAsBob();
|
||||||
|
failSetSystemStateTed();
|
||||||
|
failTedChangesPwAndLocale();
|
||||||
|
addChangePwRoleToTed();
|
||||||
|
tedChangesOwnPassAndLocale();
|
||||||
|
failTedChangesOtherPwStateAndLocale();
|
||||||
|
authAsTed();
|
||||||
|
failPerformRestrictableAsBobNoRoleApp();
|
||||||
|
addRoleAppToBob();
|
||||||
|
performRestrictableAsBob();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failSetSystemStateTed() {
|
||||||
|
try {
|
||||||
|
// testEnableUserBob
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserState(certificate, TED, UserState.SYSTEM);
|
||||||
|
fail("Should not be able to set user state to SYSTEM");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failTedChangesOtherPwStateAndLocale() {
|
||||||
|
try {
|
||||||
|
// testTedChangesOwnPwd
|
||||||
|
login(TED, ArraysHelper.copyOf(PASS_TED));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserPassword(certificate, BOB, ArraysHelper.copyOf(PASS_TED));
|
||||||
|
fail("Should not be able to set password of other user, as missing privilege");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserLocale(certificate, BOB, Locale.FRENCH);
|
||||||
|
fail("Should not be able to set locale of other user, as missing privilege");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserState(certificate, BOB, UserState.DISABLED);
|
||||||
|
fail("Should not be able to set state of other user, as missing privilege");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failTedChangesPwAndLocale() {
|
||||||
|
try {
|
||||||
|
// testTedChangesOwnPwd
|
||||||
|
login(TED, ArraysHelper.copyOf(PASS_DEF));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserPassword(certificate, TED, ArraysHelper.copyOf(PASS_TED));
|
||||||
|
fail("Should not be able to set password, as missing privilege");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserLocale(certificate, TED, Locale.FRENCH);
|
||||||
|
fail("Should not be able to set locale, as missing privilege");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
privilegeHandler.setUserState(certificate, TED, UserState.ENABLED);
|
||||||
|
fail("Should not be able to set state, as missing privilege");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
// ok
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addChangePwRoleToTed() {
|
||||||
|
try {
|
||||||
|
// add role user
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
PrivilegeRep passwordRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_SET_USER_PASSWORD,
|
||||||
|
PRIVILEGE_USER_ACCESS, false, Collections.emptySet(), Collections.emptySet());
|
||||||
|
PrivilegeRep localeRep = new PrivilegeRep(PrivilegeHandler.PRIVILEGE_SET_USER_LOCALE, PRIVILEGE_USER_ACCESS,
|
||||||
|
false, Collections.emptySet(), Collections.emptySet());
|
||||||
|
|
||||||
|
RoleRep roleRep = new RoleRep(ROLE_CHANGE_PW, Arrays.asList(passwordRep, localeRep));
|
||||||
|
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRole(certificate, roleRep);
|
||||||
|
privilegeHandler.addRoleToUser(certificate, TED, ROLE_CHANGE_PW);
|
||||||
|
logger.info("Added " + ROLE_CHANGE_PW + " to " + TED);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performRestrictableAsBob() {
|
||||||
|
try {
|
||||||
|
// testPerformRestrictableAsBob
|
||||||
|
// Tests if the user bob, who now has AppUser role can perform restrictable
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
// see if bob can perform restrictable
|
||||||
|
Restrictable restrictable = new TestRestrictable();
|
||||||
|
this.ctx.validateAction(restrictable);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRoleAppToBob() {
|
||||||
|
try {
|
||||||
|
// testAddAppRoleToBob
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRoleToUser(certificate, BOB, ROLE_APP_USER);
|
||||||
|
logger.info("Added " + ROLE_APP_USER + " to " + BOB);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failPerformRestrictableAsBobNoRoleApp() {
|
||||||
|
try {
|
||||||
|
// testFailPerformRestrictableAsBob
|
||||||
|
// Tests if the user bob, who does not have AppUser role can perform restrictable
|
||||||
|
// this will fail as bob does not have role app
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
// see if bob can perform restrictable
|
||||||
|
Restrictable restrictable = new TestRestrictable();
|
||||||
|
this.ctx.validateAction(restrictable);
|
||||||
|
fail("Should fail as bob does not have role app");
|
||||||
|
} catch (AccessDeniedException e) {
|
||||||
|
String msg = "User bob does not have the privilege ch.eitchnet.privilege.test.model.TestRestrictable needed for Restrictable ch.eitchnet.privilege.test.model.TestRestrictable";
|
||||||
|
assertEquals(msg, e.getLocalizedMessage());
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void authAsTed() {
|
||||||
|
try {
|
||||||
|
// testAuthAsTed
|
||||||
|
login(TED, ArraysHelper.copyOf(PASS_TED));
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tedChangesOwnPassAndLocale() {
|
||||||
|
try {
|
||||||
|
// testTedChangesOwnPwd
|
||||||
|
login(TED, ArraysHelper.copyOf(PASS_DEF));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.setUserPassword(certificate, TED, ArraysHelper.copyOf(PASS_TED));
|
||||||
|
privilegeHandler.setUserLocale(certificate, TED, Locale.FRENCH);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPassForTedAsBob() {
|
||||||
|
try {
|
||||||
|
// testSetTedPwdAsBob
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
// set ted's password to default
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.setUserPassword(certificate, TED, ArraysHelper.copyOf(PASS_DEF));
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failAuthAsTedNoPass() {
|
||||||
|
try {
|
||||||
|
// testFailAuthAsTedNoPass
|
||||||
|
// Will fail because user ted has no password
|
||||||
|
login(TED, ArraysHelper.copyOf(PASS_TED));
|
||||||
|
fail("User Ted may not authenticate because the user has no password!");
|
||||||
|
} catch (PrivilegeException e) {
|
||||||
|
String msg = "User ted has no password and may not login!";
|
||||||
|
assertEquals(msg, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTedAsBob() {
|
||||||
|
try {
|
||||||
|
UserRep userRep;
|
||||||
|
// testAddUserTedAsBob
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
// let's add a new user ted
|
||||||
|
HashSet<String> roles = new HashSet<>();
|
||||||
|
roles.add(ROLE_USER);
|
||||||
|
userRep = new UserRep(null, TED, "Ted", "Newman", UserState.ENABLED, roles, null,
|
||||||
|
new HashMap<String, String>());
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addUser(certificate, userRep, null);
|
||||||
|
logger.info("Added user " + TED);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRoleAdminToBob() {
|
||||||
|
try {
|
||||||
|
// testAddAdminRoleToBob
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRoleToUser(certificate, BOB, ROLE_PRIVILEGE_ADMIN);
|
||||||
|
logger.info("Added " + ROLE_PRIVILEGE_ADMIN + " to " + ADMIN);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failAddTedAsBobNotAdmin() {
|
||||||
|
Certificate certificate = null;
|
||||||
|
try {
|
||||||
|
UserRep userRep;
|
||||||
|
// testFailAddUserTedAsBob
|
||||||
|
// Will fail because user bob does not have admin rights
|
||||||
|
// auth as Bob
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
// let's add a new user Ted
|
||||||
|
userRep = new UserRep("1", TED, "Ted", "And then Some", UserState.NEW, new HashSet<String>(), null,
|
||||||
|
new HashMap<String, String>());
|
||||||
|
certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addUser(certificate, userRep, null);
|
||||||
|
fail("User bob may not add a user as bob does not have admin rights!");
|
||||||
|
} catch (PrivilegeException e) {
|
||||||
|
String msg = MessageFormat.format(PrivilegeMessages.getString("Privilege.noprivilege.user"), //$NON-NLS-1$
|
||||||
|
BOB, PrivilegeHandler.PRIVILEGE_ADD_USER);
|
||||||
|
assertEquals(msg, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void authAsBob() {
|
||||||
|
try {
|
||||||
|
// testAuthAsBob
|
||||||
|
login(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRoleUserToBob() {
|
||||||
|
try {
|
||||||
|
// testAddRoleUserToBob
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRoleToUser(certificate, BOB, ROLE_USER);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
logout();
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRoleUser() {
|
||||||
|
try {
|
||||||
|
// add role user
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
RoleRep roleRep = new RoleRep(ROLE_USER, new ArrayList<>());
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addRole(certificate, roleRep);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableBob() {
|
||||||
|
try {
|
||||||
|
// testEnableUserBob
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.setUserState(certificate, BOB, UserState.ENABLED);
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void failAuthAsBobNotEnabled() {
|
||||||
|
try {
|
||||||
|
// testFailAuthAsBob
|
||||||
|
// Will fail because user bob is not yet enabled
|
||||||
|
privilegeHandler.authenticate(BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
fail("User Bob may not authenticate because the user is not yet enabled!");
|
||||||
|
} catch (PrivilegeException e) {
|
||||||
|
String msg = "User bob does not have state ENABLED and can not login!";
|
||||||
|
assertEquals(msg, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBobAsAdmin() {
|
||||||
|
try {
|
||||||
|
login(ADMIN, ArraysHelper.copyOf(PASS_ADMIN));
|
||||||
|
|
||||||
|
// let's add a new user bob
|
||||||
|
UserRep userRep = new UserRep(null, BOB, "Bob", "Newman", UserState.NEW,
|
||||||
|
new HashSet<>(Arrays.asList(ROLE_MY)), null, new HashMap<String, String>());
|
||||||
|
Certificate certificate = this.ctx.getCertificate();
|
||||||
|
privilegeHandler.addUser(certificate, userRep, null);
|
||||||
|
logger.info("Added user " + BOB);
|
||||||
|
|
||||||
|
// set bob's password
|
||||||
|
privilegeHandler.setUserPassword(certificate, BOB, ArraysHelper.copyOf(PASS_BOB));
|
||||||
|
logger.info("Set Bob's password");
|
||||||
|
privilegeHandler.persist(certificate);
|
||||||
|
} finally {
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,454 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.handler.DefaultEncryptionHandler;
|
||||||
|
import ch.eitchnet.privilege.handler.PrivilegeHandler;
|
||||||
|
import ch.eitchnet.privilege.handler.XmlPersistenceHandler;
|
||||||
|
import ch.eitchnet.privilege.model.IPrivilege;
|
||||||
|
import ch.eitchnet.privilege.model.UserState;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeContainerModel;
|
||||||
|
import ch.eitchnet.privilege.model.internal.PrivilegeImpl;
|
||||||
|
import ch.eitchnet.privilege.model.internal.Role;
|
||||||
|
import ch.eitchnet.privilege.model.internal.User;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeConfigDomWriter;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeConfigSaxReader;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeRolesDomWriter;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeRolesSaxReader;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeUsersDomWriter;
|
||||||
|
import ch.eitchnet.privilege.xml.PrivilegeUsersSaxReader;
|
||||||
|
import ch.eitchnet.utils.helper.FileHelper;
|
||||||
|
import ch.eitchnet.utils.helper.StringHelper;
|
||||||
|
import ch.eitchnet.utils.helper.XmlHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public class XmlTest {
|
||||||
|
|
||||||
|
private static final String TARGET_TEST = "./target/test";
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(XmlTest.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
* if something goes wrong
|
||||||
|
*/
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws Exception {
|
||||||
|
|
||||||
|
cleanUp();
|
||||||
|
|
||||||
|
File tmpDir = new File("target/test");
|
||||||
|
if (tmpDir.exists())
|
||||||
|
FileHelper.deleteFile(tmpDir, false);
|
||||||
|
tmpDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanUp() throws Exception {
|
||||||
|
|
||||||
|
File tmpDir = new File("target/test");
|
||||||
|
if (!tmpDir.exists())
|
||||||
|
return;
|
||||||
|
|
||||||
|
File tmpFile = new File("target/test/PrivilegeTest.xml");
|
||||||
|
if (tmpFile.exists() && !tmpFile.delete()) {
|
||||||
|
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpFile = new File("target/test/PrivilegeUsersTest.xml");
|
||||||
|
if (tmpFile.exists() && !tmpFile.delete()) {
|
||||||
|
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpFile = new File("target/test/PrivilegeRolesTest.xml");
|
||||||
|
if (tmpFile.exists() && !tmpFile.delete()) {
|
||||||
|
throw new RuntimeException("Tmp still exists and can not be deleted at " + tmpFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
// and temporary parent
|
||||||
|
if (!tmpDir.delete()) {
|
||||||
|
throw new RuntimeException("Could not remove temporary parent for tmp " + tmpFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canReadConfig() {
|
||||||
|
|
||||||
|
PrivilegeContainerModel containerModel = new PrivilegeContainerModel();
|
||||||
|
PrivilegeConfigSaxReader saxReader = new PrivilegeConfigSaxReader(containerModel);
|
||||||
|
File xmlFile = new File("config/PrivilegeConfig.xml");
|
||||||
|
XmlHelper.parseDocument(xmlFile, saxReader);
|
||||||
|
logger.info(containerModel.toString());
|
||||||
|
|
||||||
|
// assert all objects read
|
||||||
|
assertNotNull(containerModel.getParameterMap());
|
||||||
|
assertNotNull(containerModel.getPolicies());
|
||||||
|
assertNotNull(containerModel.getEncryptionHandlerClassName());
|
||||||
|
assertNotNull(containerModel.getEncryptionHandlerParameterMap());
|
||||||
|
assertNotNull(containerModel.getPersistenceHandlerClassName());
|
||||||
|
assertNotNull(containerModel.getPersistenceHandlerParameterMap());
|
||||||
|
|
||||||
|
assertEquals(6, containerModel.getParameterMap().size());
|
||||||
|
assertEquals(3, containerModel.getPolicies().size());
|
||||||
|
assertEquals(1, containerModel.getEncryptionHandlerParameterMap().size());
|
||||||
|
assertEquals(3, containerModel.getPersistenceHandlerParameterMap().size());
|
||||||
|
|
||||||
|
// TODO extend assertions to actual model
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canWriteConfig() {
|
||||||
|
|
||||||
|
Map<String, String> parameterMap = new HashMap<>();
|
||||||
|
Map<String, String> encryptionHandlerParameterMap = new HashMap<>();
|
||||||
|
Map<String, String> persistenceHandlerParameterMap = new HashMap<>();
|
||||||
|
|
||||||
|
parameterMap.put("autoPersistOnPasswordChange", "true");
|
||||||
|
encryptionHandlerParameterMap.put("hashAlgorithm", "SHA-256");
|
||||||
|
persistenceHandlerParameterMap.put("basePath", TARGET_TEST);
|
||||||
|
persistenceHandlerParameterMap.put("modelXmlFile", "PrivilegeModel.xml");
|
||||||
|
|
||||||
|
PrivilegeContainerModel containerModel = new PrivilegeContainerModel();
|
||||||
|
containerModel.setParameterMap(parameterMap);
|
||||||
|
containerModel.setEncryptionHandlerClassName(DefaultEncryptionHandler.class.getName());
|
||||||
|
containerModel.setEncryptionHandlerParameterMap(encryptionHandlerParameterMap);
|
||||||
|
containerModel.setPersistenceHandlerClassName(XmlPersistenceHandler.class.getName());
|
||||||
|
containerModel.setPersistenceHandlerParameterMap(persistenceHandlerParameterMap);
|
||||||
|
|
||||||
|
containerModel.addPolicy("DefaultPrivilege", "ch.eitchnet.privilege.policy.DefaultPrivilege");
|
||||||
|
|
||||||
|
File configFile = new File("./target/test/PrivilegeTest.xml");
|
||||||
|
PrivilegeConfigDomWriter configSaxWriter = new PrivilegeConfigDomWriter(containerModel, configFile);
|
||||||
|
configSaxWriter.write();
|
||||||
|
|
||||||
|
String fileHash = StringHelper.getHexString(FileHelper.hashFileSha256(configFile));
|
||||||
|
assertEquals("22d4ba39605d49c758184d9bd63beae5ccf8786f3dabbab45cd9f59c2afbcbd0", fileHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canReadUsers() {
|
||||||
|
|
||||||
|
PrivilegeUsersSaxReader xmlHandler = new PrivilegeUsersSaxReader();
|
||||||
|
File xmlFile = new File("config/PrivilegeUsers.xml");
|
||||||
|
XmlHelper.parseDocument(xmlFile, xmlHandler);
|
||||||
|
|
||||||
|
List<User> users = xmlHandler.getUsers();
|
||||||
|
assertNotNull(users);
|
||||||
|
|
||||||
|
assertEquals(3, users.size());
|
||||||
|
|
||||||
|
//
|
||||||
|
// users
|
||||||
|
//
|
||||||
|
|
||||||
|
// admin
|
||||||
|
User admin = findUser("admin", users);
|
||||||
|
assertEquals("1", admin.getUserId());
|
||||||
|
assertEquals("admin", admin.getUsername());
|
||||||
|
assertEquals("8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918", admin.getPassword());
|
||||||
|
assertEquals("Application", admin.getFirstname());
|
||||||
|
assertEquals("Administrator", admin.getLastname());
|
||||||
|
assertEquals(UserState.ENABLED, admin.getUserState());
|
||||||
|
assertEquals("en_gb", admin.getLocale().toString());
|
||||||
|
assertThat(admin.getRoles(), containsInAnyOrder("PrivilegeAdmin", "AppUser"));
|
||||||
|
Map<String, String> properties = admin.getProperties();
|
||||||
|
assertEquals(new HashSet<>(Arrays.asList("organization", "organizationalUnit")), properties.keySet());
|
||||||
|
assertEquals("eitchnet.ch", properties.get("organization"));
|
||||||
|
assertEquals("Development", properties.get("organizationalUnit"));
|
||||||
|
|
||||||
|
// system_admin
|
||||||
|
User systemAdmin = findUser("system_admin", users);
|
||||||
|
assertEquals("2", systemAdmin.getUserId());
|
||||||
|
assertEquals("system_admin", systemAdmin.getUsername());
|
||||||
|
assertEquals(null, systemAdmin.getPassword());
|
||||||
|
assertEquals("System User", systemAdmin.getFirstname());
|
||||||
|
assertEquals("Administrator", systemAdmin.getLastname());
|
||||||
|
assertEquals(UserState.SYSTEM, systemAdmin.getUserState());
|
||||||
|
assertEquals("en_gb", systemAdmin.getLocale().toString());
|
||||||
|
assertThat(systemAdmin.getRoles(), containsInAnyOrder("system_admin_privileges"));
|
||||||
|
assertTrue(systemAdmin.getProperties().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canReadRoles() {
|
||||||
|
|
||||||
|
PrivilegeRolesSaxReader xmlHandler = new PrivilegeRolesSaxReader();
|
||||||
|
File xmlFile = new File("config/PrivilegeRoles.xml");
|
||||||
|
XmlHelper.parseDocument(xmlFile, xmlHandler);
|
||||||
|
|
||||||
|
List<Role> roles = xmlHandler.getRoles();
|
||||||
|
assertNotNull(roles);
|
||||||
|
|
||||||
|
assertEquals(6, roles.size());
|
||||||
|
|
||||||
|
// assert model
|
||||||
|
|
||||||
|
//
|
||||||
|
// roles
|
||||||
|
//
|
||||||
|
|
||||||
|
// PrivilegeAdmin
|
||||||
|
Role privilegeAdmin = findRole("PrivilegeAdmin", roles);
|
||||||
|
assertEquals("PrivilegeAdmin", privilegeAdmin.getName());
|
||||||
|
assertEquals(14, privilegeAdmin.getPrivilegeNames().size());
|
||||||
|
IPrivilege privilegeAction = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ACTION);
|
||||||
|
assertFalse(privilegeAction.isAllAllowed());
|
||||||
|
assertEquals(3, privilegeAction.getAllowList().size());
|
||||||
|
assertEquals(0, privilegeAction.getDenyList().size());
|
||||||
|
assertEquals("DefaultPrivilege", privilegeAction.getPolicy());
|
||||||
|
|
||||||
|
IPrivilege privilegeAddRole = privilegeAdmin.getPrivilege(PrivilegeHandler.PRIVILEGE_ADD_ROLE);
|
||||||
|
assertTrue(privilegeAddRole.isAllAllowed());
|
||||||
|
assertEquals(0, privilegeAddRole.getAllowList().size());
|
||||||
|
assertEquals(0, privilegeAddRole.getDenyList().size());
|
||||||
|
|
||||||
|
IPrivilege privilegeRemRoleFromUser = privilegeAdmin
|
||||||
|
.getPrivilege(PrivilegeHandler.PRIVILEGE_REMOVE_ROLE_FROM_USER);
|
||||||
|
assertTrue(privilegeRemRoleFromUser.isAllAllowed());
|
||||||
|
assertEquals(0, privilegeRemRoleFromUser.getAllowList().size());
|
||||||
|
assertEquals(0, privilegeRemRoleFromUser.getDenyList().size());
|
||||||
|
|
||||||
|
// AppUser
|
||||||
|
Role appUser = findRole("AppUser", roles);
|
||||||
|
assertEquals("AppUser", appUser.getName());
|
||||||
|
assertEquals(new HashSet<>(Arrays.asList("ch.eitchnet.privilege.test.model.TestRestrictable")),
|
||||||
|
appUser.getPrivilegeNames());
|
||||||
|
|
||||||
|
IPrivilege testRestrictable = appUser.getPrivilege("ch.eitchnet.privilege.test.model.TestRestrictable");
|
||||||
|
assertEquals("ch.eitchnet.privilege.test.model.TestRestrictable", testRestrictable.getName());
|
||||||
|
assertEquals("DefaultPrivilege", testRestrictable.getPolicy());
|
||||||
|
assertTrue(testRestrictable.isAllAllowed());
|
||||||
|
assertEquals(0, testRestrictable.getAllowList().size());
|
||||||
|
assertEquals(0, testRestrictable.getDenyList().size());
|
||||||
|
|
||||||
|
// system_admin_privileges
|
||||||
|
Role systemAdminPrivileges = findRole("system_admin_privileges", roles);
|
||||||
|
assertEquals("system_admin_privileges", systemAdminPrivileges.getName());
|
||||||
|
assertEquals(2, systemAdminPrivileges.getPrivilegeNames().size());
|
||||||
|
assertThat(systemAdminPrivileges.getPrivilegeNames(),
|
||||||
|
containsInAnyOrder("ch.eitchnet.privilege.handler.SystemUserAction",
|
||||||
|
"ch.eitchnet.privilege.test.model.TestSystemRestrictable"));
|
||||||
|
|
||||||
|
IPrivilege testSystemUserAction = systemAdminPrivileges
|
||||||
|
.getPrivilege("ch.eitchnet.privilege.handler.SystemUserAction");
|
||||||
|
assertEquals("ch.eitchnet.privilege.handler.SystemUserAction", testSystemUserAction.getName());
|
||||||
|
assertEquals("DefaultPrivilege", testSystemUserAction.getPolicy());
|
||||||
|
assertFalse(testSystemUserAction.isAllAllowed());
|
||||||
|
assertEquals(1, testSystemUserAction.getAllowList().size());
|
||||||
|
assertEquals(1, testSystemUserAction.getDenyList().size());
|
||||||
|
|
||||||
|
IPrivilege testSystemRestrictable = systemAdminPrivileges
|
||||||
|
.getPrivilege("ch.eitchnet.privilege.test.model.TestSystemRestrictable");
|
||||||
|
assertEquals("ch.eitchnet.privilege.test.model.TestSystemRestrictable", testSystemRestrictable.getName());
|
||||||
|
assertEquals("DefaultPrivilege", testSystemRestrictable.getPolicy());
|
||||||
|
assertTrue(testSystemRestrictable.isAllAllowed());
|
||||||
|
assertEquals(0, testSystemRestrictable.getAllowList().size());
|
||||||
|
assertEquals(0, testSystemRestrictable.getDenyList().size());
|
||||||
|
|
||||||
|
// restrictedRole
|
||||||
|
Role restrictedRole = findRole("restrictedRole", roles);
|
||||||
|
assertEquals("restrictedRole", restrictedRole.getName());
|
||||||
|
assertEquals(1, restrictedRole.getPrivilegeNames().size());
|
||||||
|
assertThat(restrictedRole.getPrivilegeNames(),
|
||||||
|
containsInAnyOrder("ch.eitchnet.privilege.handler.SystemUserAction"));
|
||||||
|
|
||||||
|
IPrivilege testSystemUserAction2 = restrictedRole
|
||||||
|
.getPrivilege("ch.eitchnet.privilege.handler.SystemUserAction");
|
||||||
|
assertEquals("ch.eitchnet.privilege.handler.SystemUserAction", testSystemUserAction2.getName());
|
||||||
|
assertEquals("DefaultPrivilege", testSystemUserAction2.getPolicy());
|
||||||
|
assertFalse(testSystemUserAction2.isAllAllowed());
|
||||||
|
assertEquals(1, testSystemUserAction2.getAllowList().size());
|
||||||
|
assertEquals(1, testSystemUserAction2.getDenyList().size());
|
||||||
|
assertThat(testSystemUserAction2.getAllowList(), containsInAnyOrder("hello"));
|
||||||
|
assertThat(testSystemUserAction2.getDenyList(), containsInAnyOrder("goodbye"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username
|
||||||
|
* @param users
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private User findUser(String username, List<User> users) {
|
||||||
|
for (User user : users) {
|
||||||
|
if (user.getUsername().equals(username))
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("No user exists with username " + username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @param roles
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Role findRole(String name, List<Role> roles) {
|
||||||
|
for (Role role : roles) {
|
||||||
|
if (role.getName().equals(name))
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("No role exists with name " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canWriteUsers() {
|
||||||
|
|
||||||
|
Map<String, String> propertyMap;
|
||||||
|
Set<String> userRoles;
|
||||||
|
|
||||||
|
List<User> users = new ArrayList<>();
|
||||||
|
propertyMap = new HashMap<>();
|
||||||
|
propertyMap.put("prop1", "value1");
|
||||||
|
userRoles = new HashSet<>();
|
||||||
|
userRoles.add("role1");
|
||||||
|
User user1 = new User("1", "user1", "blabla", "Bob", "White", UserState.DISABLED, userRoles, Locale.ENGLISH,
|
||||||
|
propertyMap);
|
||||||
|
users.add(user1);
|
||||||
|
|
||||||
|
propertyMap = new HashMap<>();
|
||||||
|
propertyMap.put("prop2", "value2");
|
||||||
|
userRoles = new HashSet<>();
|
||||||
|
userRoles.add("role2");
|
||||||
|
User user2 = new User("2", "user2", "haha", "Leonard", "Sheldon", UserState.ENABLED, userRoles, Locale.ENGLISH,
|
||||||
|
propertyMap);
|
||||||
|
users.add(user2);
|
||||||
|
|
||||||
|
File modelFile = new File("./target/test/PrivilegeUsersTest.xml");
|
||||||
|
PrivilegeUsersDomWriter configSaxWriter = new PrivilegeUsersDomWriter(users, modelFile);
|
||||||
|
configSaxWriter.write();
|
||||||
|
|
||||||
|
PrivilegeUsersSaxReader xmlHandler = new PrivilegeUsersSaxReader();
|
||||||
|
XmlHelper.parseDocument(modelFile, xmlHandler);
|
||||||
|
|
||||||
|
List<User> parsedUsers = xmlHandler.getUsers();
|
||||||
|
assertNotNull(parsedUsers);
|
||||||
|
assertEquals(2, parsedUsers.size());
|
||||||
|
|
||||||
|
User parsedUser1 = parsedUsers.stream().filter(u -> u.getUsername().equals("user1")).findAny().get();
|
||||||
|
User parsedUser2 = parsedUsers.stream().filter(u -> u.getUsername().equals("user2")).findAny().get();
|
||||||
|
|
||||||
|
assertEquals(user1.getFirstname(), parsedUser1.getFirstname());
|
||||||
|
assertEquals(user1.getLastname(), parsedUser1.getLastname());
|
||||||
|
assertEquals(user1.getLocale(), parsedUser1.getLocale());
|
||||||
|
assertEquals(user1.getPassword(), parsedUser1.getPassword());
|
||||||
|
assertEquals(user1.getProperties(), parsedUser1.getProperties());
|
||||||
|
assertEquals(user1.getUserId(), parsedUser1.getUserId());
|
||||||
|
assertEquals(user1.getUserState(), parsedUser1.getUserState());
|
||||||
|
assertEquals(user1.getRoles(), parsedUser1.getRoles());
|
||||||
|
|
||||||
|
assertEquals(user2.getFirstname(), parsedUser2.getFirstname());
|
||||||
|
assertEquals(user2.getLastname(), parsedUser2.getLastname());
|
||||||
|
assertEquals(user2.getLocale(), parsedUser2.getLocale());
|
||||||
|
assertEquals(user2.getPassword(), parsedUser2.getPassword());
|
||||||
|
assertEquals(user2.getProperties(), parsedUser2.getProperties());
|
||||||
|
assertEquals(user2.getUserId(), parsedUser2.getUserId());
|
||||||
|
assertEquals(user2.getUserState(), parsedUser2.getUserState());
|
||||||
|
assertEquals(user2.getRoles(), parsedUser2.getRoles());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canWriteRoles() {
|
||||||
|
|
||||||
|
Map<String, IPrivilege> privilegeMap;
|
||||||
|
List<Role> roles = new ArrayList<>();
|
||||||
|
Set<String> list = Collections.emptySet();
|
||||||
|
privilegeMap = new HashMap<>();
|
||||||
|
privilegeMap.put("priv1", new PrivilegeImpl("priv1", "DefaultPrivilege", true, list, list));
|
||||||
|
Role role1 = new Role("role1", privilegeMap);
|
||||||
|
roles.add(role1);
|
||||||
|
|
||||||
|
privilegeMap = new HashMap<>();
|
||||||
|
Set<String> denyList = new HashSet<>();
|
||||||
|
denyList.add("myself");
|
||||||
|
Set<String> allowList = new HashSet<>();
|
||||||
|
allowList.add("other");
|
||||||
|
privilegeMap.put("priv2", new PrivilegeImpl("priv2", "DefaultPrivilege", false, denyList, allowList));
|
||||||
|
Role role2 = new Role("role2", privilegeMap);
|
||||||
|
roles.add(role2);
|
||||||
|
|
||||||
|
File modelFile = new File("./target/test/PrivilegeRolesTest.xml");
|
||||||
|
PrivilegeRolesDomWriter configSaxWriter = new PrivilegeRolesDomWriter(roles, modelFile);
|
||||||
|
configSaxWriter.write();
|
||||||
|
|
||||||
|
PrivilegeRolesSaxReader xmlHandler = new PrivilegeRolesSaxReader();
|
||||||
|
XmlHelper.parseDocument(modelFile, xmlHandler);
|
||||||
|
|
||||||
|
List<Role> parsedRoles = xmlHandler.getRoles();
|
||||||
|
assertNotNull(parsedRoles);
|
||||||
|
assertEquals(2, parsedRoles.size());
|
||||||
|
|
||||||
|
assertEquals(2, parsedRoles.size());
|
||||||
|
Role parsedRole1 = parsedRoles.stream().filter(r -> r.getName().equals("role1")).findAny().get();
|
||||||
|
Role parsedRole2 = parsedRoles.stream().filter(r -> r.getName().equals("role2")).findAny().get();
|
||||||
|
|
||||||
|
Set<String> privilegeNames = role1.getPrivilegeNames();
|
||||||
|
assertEquals(privilegeNames, parsedRole1.getPrivilegeNames());
|
||||||
|
for (String privilegeName : privilegeNames) {
|
||||||
|
IPrivilege privilege = role1.getPrivilege(privilegeName);
|
||||||
|
IPrivilege privilege2 = parsedRole1.getPrivilege(privilegeName);
|
||||||
|
assertNotNull(privilege);
|
||||||
|
assertNotNull(privilege2);
|
||||||
|
|
||||||
|
assertEquals(privilege.isAllAllowed(), privilege2.isAllAllowed());
|
||||||
|
assertEquals(privilege.getAllowList(), privilege2.getAllowList());
|
||||||
|
assertEquals(privilege.getDenyList(), privilege2.getDenyList());
|
||||||
|
assertEquals(privilege.getName(), privilege2.getName());
|
||||||
|
assertEquals(privilege.getPolicy(), privilege2.getPolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(role2.getPrivilegeNames(), parsedRole2.getPrivilegeNames());
|
||||||
|
privilegeNames = role2.getPrivilegeNames();
|
||||||
|
for (String privilegeName : privilegeNames) {
|
||||||
|
IPrivilege privilege = role2.getPrivilege(privilegeName);
|
||||||
|
IPrivilege privilege2 = parsedRole2.getPrivilege(privilegeName);
|
||||||
|
assertNotNull(privilege);
|
||||||
|
assertNotNull(privilege2);
|
||||||
|
|
||||||
|
assertEquals(privilege.isAllAllowed(), privilege2.isAllAllowed());
|
||||||
|
assertEquals(privilege.getAllowList(), privilege2.getAllowList());
|
||||||
|
assertEquals(privilege.getDenyList(), privilege2.getDenyList());
|
||||||
|
assertEquals(privilege.getName(), privilege2.getName());
|
||||||
|
assertEquals(privilege.getPolicy(), privilege2.getPolicy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TestRestrictable implements Restrictable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeName()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getPrivilegeName() {
|
||||||
|
return TestRestrictable.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeValue()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object getPrivilegeValue() {
|
||||||
|
return TestRestrictable.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.model.Restrictable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TestSystemRestrictable implements Restrictable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeName()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getPrivilegeName() {
|
||||||
|
return TestSystemRestrictable.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeValue()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object getPrivilegeValue() {
|
||||||
|
return TestSystemRestrictable.class.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.handler.SystemUserAction;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TestSystemUserAction extends SystemUserAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PrivilegeContext context) {
|
||||||
|
TestSystemRestrictable restrictable = new TestSystemRestrictable();
|
||||||
|
context.validateAction(restrictable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed 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 ch.eitchnet.privilege.test.model;
|
||||||
|
|
||||||
|
import ch.eitchnet.privilege.handler.SystemUserAction;
|
||||||
|
import ch.eitchnet.privilege.model.PrivilegeContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TestSystemUserActionDeny extends SystemUserAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(PrivilegeContext privilegeContext) {
|
||||||
|
TestRestrictable restrictable = new TestRestrictable();
|
||||||
|
privilegeContext.validateAction(restrictable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE log4j:configuration PUBLIC
|
||||||
|
"-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
|
||||||
|
<log4j:configuration debug="false" xmlns:log4j='http://jakarta.apache.org/log4j/'>
|
||||||
|
|
||||||
|
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<param name="ConversionPattern" value="%d %5p [%t] %C{1} %M - %m%n" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<appender name="FILE" class="org.apache.log4j.FileAppender">
|
||||||
|
<param name="File" value="sample.log"/>
|
||||||
|
<param name="BufferedIO" value="true" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<param name="ConversionPattern" value="%d %5p [%t] %C{1} %M - %m%n" />
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="ch.eitchnet">
|
||||||
|
<level value="info" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<priority value="info" />
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
<!-- appender-ref ref="FILE" / -->
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</log4j:configuration>
|
Loading…
Reference in New Issue