Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b97237c6ef | |||
| e15470e783 | |||
| bdec47bd4a | |||
| 48c7285872 | |||
| 464115320f | |||
| a1afe18af5 | |||
| bcdbbb4f24 | |||
| b2be58e5da | |||
| 1a738553b4 | |||
| 71a046eb0a | |||
| c733611568 | |||
| a6294cb701 | |||
| 7862d9965b | |||
| 2620d036ab | |||
| eed779c7e9 | |||
| dd53b3533c | |||
| 005e0a6730 | |||
| af3d62e9b5 | |||
| df5166e82d | |||
| 36978a49e8 | |||
| 06a7a5099a | |||
| e7438db1de | |||
| d14f6c1347 | |||
| ebe3c742cc | |||
| ee9ea07249 | |||
| ce422b042e | |||
| ce11407d96 | |||
| 1c2c952e2a | |||
| 48804fff88 | |||
| 00077cdd4d | |||
| c7ae9c6eeb | |||
| 25706255a3 | |||
| 83a616b02c | |||
| 9191438acf | |||
| 86f37ce7c1 | |||
| d244e8e0cb | |||
| 2aa8d18531 | |||
| d25f656a48 | |||
| 8227656cb0 | |||
| 086e2b3d2b | |||
| 7d63246f6b | |||
| 8c5e83cf34 | |||
| bf15ee8a6d | |||
| 1c90e77100 | |||
| 62319b4d1c | |||
| 0c7490a25d | |||
| b80c25224c | |||
| 1690b17cb4 | |||
| fc0cf54962 | |||
| 650b0f71b1 | |||
| b67c026a16 | |||
| ccb4a8a2bb | |||
| 1a150a334a | |||
| c340c6914f | |||
| 77167c0d39 | |||
| 1ca26dffbf | |||
| 56978cfc90 | |||
| 874b7f5d2a | |||
| 79f6cf8995 | |||
| c3ac7c0412 | |||
| b8773f1166 | |||
| 9c7287c64f | |||
| b2d37a048f | |||
| 9cf6869c5d | |||
| 34fb3af7d3 | |||
| 7e6493ef7b | |||
| 92c5b852c1 | |||
| c8c4904199 | |||
| c0bf3ce1b5 | |||
| 85ed196cf4 | |||
| 1075f57db4 | |||
| c50a836cd3 | |||
| 8281d5c33b | |||
| 171918e41a |
@@ -1,7 +0,0 @@
|
||||
dist
|
||||
target
|
||||
build.properties
|
||||
*.log
|
||||
.clover
|
||||
*.keystore
|
||||
server-work
|
||||
@@ -0,0 +1,8 @@
|
||||
#*
|
||||
.#*
|
||||
*~
|
||||
_site
|
||||
.idea
|
||||
*.sw[op]
|
||||
.project
|
||||
sample-pages
|
||||
@@ -0,0 +1 @@
|
||||
spring-gh-pages
|
||||
@@ -0,0 +1 @@
|
||||
ruby-2.2.0
|
||||
@@ -1,57 +0,0 @@
|
||||
#Mon Nov 07 22:01:53 EST 2005
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
@@ -1,3 +0,0 @@
|
||||
#Mon Nov 07 21:58:48 EST 2005
|
||||
eclipse.preferences.version=1
|
||||
internal.default.compliance=default
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (4.2.6)
|
||||
i18n (~> 0.7)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.4.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.10.0)
|
||||
colorator (0.1)
|
||||
ethon (0.9.0)
|
||||
ffi (>= 1.3.0)
|
||||
execjs (2.7.0)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.13)
|
||||
gemoji (2.1.0)
|
||||
github-pages (86)
|
||||
github-pages-health-check (= 1.1.0)
|
||||
jekyll (= 3.1.6)
|
||||
jekyll-coffeescript (= 1.0.1)
|
||||
jekyll-feed (= 0.5.1)
|
||||
jekyll-gist (= 1.4.0)
|
||||
jekyll-github-metadata (= 2.0.2)
|
||||
jekyll-mentions (= 1.1.3)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-redirect-from (= 0.10.0)
|
||||
jekyll-sass-converter (= 1.3.0)
|
||||
jekyll-seo-tag (= 2.0.0)
|
||||
jekyll-sitemap (= 0.10.0)
|
||||
jemoji (= 0.6.2)
|
||||
kramdown (= 1.11.1)
|
||||
liquid (= 3.0.6)
|
||||
listen (= 3.0.6)
|
||||
mercenary (~> 0.3)
|
||||
rouge (= 1.11.1)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.1.0)
|
||||
addressable (~> 2.3)
|
||||
net-dns (~> 0.8)
|
||||
octokit (~> 4.0)
|
||||
public_suffix (~> 1.4)
|
||||
typhoeus (~> 0.7)
|
||||
html-pipeline (2.4.1)
|
||||
activesupport (>= 2, < 5)
|
||||
nokogiri (>= 1.4)
|
||||
i18n (0.7.0)
|
||||
jekyll (3.1.6)
|
||||
colorator (~> 0.1)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 1.1)
|
||||
kramdown (~> 1.3)
|
||||
liquid (~> 3.0)
|
||||
mercenary (~> 0.3.3)
|
||||
rouge (~> 1.7)
|
||||
safe_yaml (~> 1.0)
|
||||
jekyll-coffeescript (1.0.1)
|
||||
coffee-script (~> 2.2)
|
||||
jekyll-feed (0.5.1)
|
||||
jekyll-gist (1.4.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.0.2)
|
||||
jekyll (~> 3.1)
|
||||
octokit (~> 4.0)
|
||||
jekyll-mentions (1.1.3)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-redirect-from (0.10.0)
|
||||
jekyll (>= 2.0)
|
||||
jekyll-sass-converter (1.3.0)
|
||||
sass (~> 3.2)
|
||||
jekyll-seo-tag (2.0.0)
|
||||
jekyll (~> 3.1)
|
||||
jekyll-sitemap (0.10.0)
|
||||
jekyll-watch (1.4.0)
|
||||
listen (~> 3.0, < 3.1)
|
||||
jemoji (0.6.2)
|
||||
gemoji (~> 2.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0)
|
||||
json (1.8.3)
|
||||
kramdown (1.11.1)
|
||||
liquid (3.0.6)
|
||||
listen (3.0.6)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9.7)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.1.0)
|
||||
minitest (5.9.0)
|
||||
multipart-post (2.0.0)
|
||||
net-dns (0.8.0)
|
||||
nokogiri (1.6.8)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
pkg-config (~> 1.1.7)
|
||||
octokit (4.3.0)
|
||||
sawyer (~> 0.7.0, >= 0.5.3)
|
||||
pkg-config (1.1.7)
|
||||
public_suffix (1.5.3)
|
||||
rb-fsevent (0.9.7)
|
||||
rb-inotify (0.9.7)
|
||||
ffi (>= 0.5.0)
|
||||
rouge (1.11.1)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.4.22)
|
||||
sawyer (0.7.0)
|
||||
addressable (>= 2.3.5, < 2.5)
|
||||
faraday (~> 0.8, < 0.10)
|
||||
terminal-table (1.6.0)
|
||||
thread_safe (0.3.5)
|
||||
typhoeus (0.8.0)
|
||||
ethon (>= 0.8.0)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
github-pages
|
||||
rouge
|
||||
|
||||
BUNDLED WITH
|
||||
1.12.5
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
# Introduction
|
||||
|
||||
Spring's project pages are based on [Jekyll](https://jekyllrb.com) and [GitHub Pages](https://pages.github.com/). This means that each project's website is stored within the project repo, in a special branch called "gh-pages". In order to keep everything looking similar across the many individual Spring projects, common elements of the Jekyll site layout, css, etc are stored in [a shared gh-pages repository](https://github.com/spring-projects/gh-pages). If you're seeing this README in the gh-pages branch of an actual Spring project, that's because this file, along with all the other common files get merged periodically into each project.
|
||||
|
||||
This approach may sound a little funky (and it is), but it's way better than the misery of Git submodules. In fact, it's actually pretty easy. If you're just getting started, then follow the directions immediately below. If you're needing a refresher on how to keep things up to date, then head to the section at the bottom on "keeping up to date".
|
||||
|
||||
> ***Note:*** Github changed their rendering (a lot) in April 2016. If you are seeing pages build failures since that time, then you probably need to merge some changes from this upstream. Follow the instructions below, and for testing locally use rubiy 2.x and don't forget to `bundle exec ...` everything.
|
||||
|
||||
|
||||
|
||||
# How to start a new `gh-pages` project page
|
||||
|
||||
From within your Spring project's git checkout directory:
|
||||
|
||||
### Create and checkout the gh-pages branch
|
||||
|
||||
git checkout --orphan gh-pages
|
||||
|
||||
### Remove all files
|
||||
|
||||
git rm -rf `git ls-files` && rm -rf *
|
||||
|
||||
### Add the gh-pages-upstream remote
|
||||
|
||||
git remote add gh-pages-upstream https://github.com/spring-projects/gh-pages.git
|
||||
|
||||
### Pull in the common site infrastructure
|
||||
|
||||
git pull gh-pages-upstream gh-pages
|
||||
|
||||
|
||||
## Edit `_config.yml`
|
||||
|
||||
You'll need to tweak a few settings in `_config.yml`, sitting in the root directory. Edit this file and follow the instructions within. It should be self explanatory; you'll see that there are lots of instances of "spring-framework" as a project name. You should replace these with your own project's information as appropriate.
|
||||
|
||||
|
||||
## Create the project home page
|
||||
|
||||
### What kind of project are you?
|
||||
|
||||
At this point, you just need to give your project a home page. There are pre-fab samples included in the `_sample-pages` directory:
|
||||
|
||||
$ ls -1 _sample-pages
|
||||
documentation.md
|
||||
project_group.html
|
||||
project.html
|
||||
vaniall.md
|
||||
|
||||
At this point you need to make a decision: is your project a "grouping project", like Spring Data, acting as a parent for one or more child projects? If so, you should choose `project_group.html` in the following step. Otherwise, if you're dealing with an individual, concrete Spring project, e.g. Spring Data JPA, or Spring Security OAuth, you should choose `project.html`. The `documentation.md` can be used when you want to expose README.md files on your site.
|
||||
|
||||
### Copy the sample page to `index.html`
|
||||
|
||||
Based on your choice above, copy the correct sample page to `index.html`, e.g.:
|
||||
|
||||
$ cp _sample-pages/project.html index.html
|
||||
|
||||
or
|
||||
|
||||
$ cp _sample-pages/project_group.html index.html
|
||||
|
||||
|
||||
## Edit the content of your home page
|
||||
|
||||
### Edit the YAML front matter
|
||||
|
||||
Open up `index.html` in your favorite text editor. Within, you'll find "YAML front matter" at the top of the file, i.e. everything between the triple dashes that look like `---`. This section contains some basic metadata, and—if you've copied the `project.html` sample—also contains a custom section of information for your project "badges". These are icons that will render in the sidebar of your project page.
|
||||
|
||||
Edit the URLs and other values in the YAML front matter as appropriate. This should be self-explanatory.
|
||||
|
||||
> **Tip**: If a particular "badge" (e.g. Sonar) does not apply to your project, just delete that entry from the YAML.
|
||||
|
||||
### Understand the use of "captures" and "includes"
|
||||
|
||||
Next, you'll see a series of `{% capture variable_name %}` blocks that look like this:
|
||||
|
||||
{% capture billboard_description %}
|
||||
...
|
||||
{% endcapture %}
|
||||
|
||||
At the end of the file you'll see a `{% include %}` directive that looks like this:
|
||||
|
||||
{% include project_page.html %}
|
||||
|
||||
That `include` directive is the most important part. It brings in `project_page.html`, which will actually be responsible for rendering the page content.
|
||||
|
||||
The net effect is that you have one simple place to edit actual page content, and the actual rendering and placement of that content is handled for you by the include.
|
||||
|
||||
Ideally, you shouldn't have to touch any other files besides `_config.yml` and `index.html`, but of course if you need to you always can.
|
||||
|
||||
### Replace the filler text with copy specific to your project
|
||||
|
||||
Of course the next step is simply to change the prose within each `{% capture %}` block to read as you want it to. It's just Markdown, so do as you please with that in mind. Note that you'll want to move on to the next step to view the site locally before you get too far into the editing process; this will allow you view your changes live as you make them.
|
||||
|
||||
|
||||
## View the site locally
|
||||
|
||||
Assuming you're already within your project's clone directory, and you've already checked out the `gh-pages` branch, follow these simple directions to view your site locally:
|
||||
|
||||
### Install jekyll if you have not already
|
||||
|
||||
> **Note:** Jekyll 3.0.4 is a known good version, and it is specifically referred to in `Gemfile.lock` so you have to use `bundle` (not `gem install ...`) to install it:
|
||||
|
||||
gem install bundler
|
||||
bundle
|
||||
|
||||
### Run jekyll
|
||||
|
||||
Use the `--watch` flag to pick up changes to files as you make them, allowing you a nice edit-and-refresh workflow.
|
||||
|
||||
bundle exec jekyll serve --watch
|
||||
|
||||
> **Important:** Because the `baseurl` is set explicitly within your project's `_config.yml` file, you'll need to fully-qualify the URL to view your project. For example, if your project is named "spring-xyz", your URL when running Jekyll locally will be <http://localhost:4000/spring-xyz/>. Don't forget the trailing slash! You'll get a 404 without it.
|
||||
|
||||
|
||||
## Commit your changes
|
||||
|
||||
Once you're satisified with your edits, commit your changes and push the `gh-pages` pages up to your project's `origin` remote.
|
||||
|
||||
git commit -m "Initialize project page"
|
||||
git push --set-upstream origin gh-pages
|
||||
git push
|
||||
|
||||
|
||||
## View your site live on the web
|
||||
|
||||
That's it! After not more than a few minutes, you should be able to see your site at https://spring-projects.github.io/{your-spring-project}
|
||||
|
||||
|
||||
# How to keep common gh-pages content up to date
|
||||
|
||||
Once you've set up your project's gh-pages infrastructure above, you'll get notified whenever
|
||||
changes are made to the shared gh-pages project. Actually, _your project_ will get notified,
|
||||
because a webhook configured on the gh-pages project will fire that ultimately creates a new
|
||||
issue in your project's GH Issues.
|
||||
> Yeah, it would have been nice to do proper pull requests instead of issues, but this arrangement
|
||||
with gh-pages branches and upstreams isn't based on forking. That means pull requests are no can do.
|
||||
This also means that if your project doesn't have issues turned on, you won't get notified! So you
|
||||
might consider doing that if you haven't already.
|
||||
|
||||
In any case, whether or not you get notified via the issue coming in from the webhook, sync'ing
|
||||
up to the latest from the shared gh-pages project is easy enough:
|
||||
|
||||
> This assumes you've got the `gh-pages-upstream` remote set up, per the instructions in sections
|
||||
above.
|
||||
|
||||
git checkout gh-pages
|
||||
git pull --no-ff gh-pages-upstream gh-pages
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
### Global gh-pages pre-amble
|
||||
safe: true
|
||||
lsi: false
|
||||
highlighter: rouge
|
||||
markdown: kramdown
|
||||
encoding: UTF-8
|
||||
github: [metadata]
|
||||
kramdown:
|
||||
input: GFM
|
||||
hard_wrap: false
|
||||
smart_quotes: ["apos", "apos", "quot", "quot"]
|
||||
gems:
|
||||
- jekyll-coffeescript
|
||||
- jekyll-paginate
|
||||
|
||||
### The following properties will change on a project-by-project basis
|
||||
|
||||
# Context path in the remote website (usually /<project>), will be prepended to absolute URLs for static resources
|
||||
baseurl: /spring-security
|
||||
|
||||
# Name of the project for display in places like page titles
|
||||
name: Spring Security
|
||||
|
||||
# ID of the project in the metadata API at spring.io (if this is not a
|
||||
# valid project ID the javascript widgets in the home page will not work)
|
||||
project: spring-security
|
||||
|
||||
# Project github URL
|
||||
github_repo_url: https://github.com/spring-projects/spring-security
|
||||
|
||||
## Custom properties
|
||||
guides_base_url: https://docs.spring.io/spring-security/site/docs/current/guides/html5/
|
||||
|
||||
# If you want to include a custom pom.xml or gradle template set these value to true and add _include files
|
||||
custom_pom_template: false
|
||||
custom_gradle_template: false
|
||||
|
||||
# If you want to include a custom pom.xml or gradle template set these value to true and add _include files
|
||||
custom_pom_template: false
|
||||
custom_gradle_template: false
|
||||
|
||||
|
||||
### The following properties are constant for most projects
|
||||
|
||||
main_site_url: https://spring.io
|
||||
projects_site_url: https://projects.spring.io
|
||||
questions_url: https://spring.io/questions
|
||||
@@ -0,0 +1,16 @@
|
||||
{% if page.badges.twitter %}
|
||||
<div class="project-sub-link">
|
||||
<a href="https://twitter.com/{{ page.badges.twitter }}">
|
||||
<div class="spring-icon project-badges twitter" title="Twitter">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for badge in page.badges.custom %}
|
||||
<div class="project-sub-link">
|
||||
<a href="{{ badge.url }}">
|
||||
<div class="spring-icon project-badges {{ badge.icon }}" title="{{ badge.name }}">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,38 @@
|
||||
<div class="billboard--wrapper project-header--wrapper">
|
||||
<div class="billboard--container">
|
||||
<div class="project-icon">
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span8 billboard--area">
|
||||
<div class="content--title">
|
||||
{% capture breadcrumb %}
|
||||
[Projects]({{ site.projects_site_url }}){% if parent_link %} : {{ parent_link }}{% endif %}
|
||||
{% endcapture %}
|
||||
{{ breadcrumb | markdownify }}
|
||||
</div>
|
||||
|
||||
<div class="project--title">{{ site.name }}
|
||||
<div class="project--links--container">
|
||||
<a href="{{ site.github_repo_url }}" class="project-link">
|
||||
<i class="icon-github"></i>
|
||||
</a>
|
||||
{% if site.forum %}
|
||||
<a href="{{ site.forum }}" class="project-link project-link-forum">
|
||||
<div class="spring-icon spring-icon-forum">
|
||||
</div>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="project--description">
|
||||
{{ billboard_description | markdownify }}
|
||||
</div>
|
||||
|
||||
{{ billboard_quickstart_button }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
dependencies {
|
||||
compile '{@= groupId @}:spring-security-web:{@= version @}'
|
||||
compile '{@= groupId @}:spring-security-config:{@= version @}'
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<div class="js-documentation-widget">
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<div id="download-widget">
|
||||
<div class="row-fluid download-widget--container">
|
||||
<div class="download-widget--header js-item-dropdown-widget--wrapper">
|
||||
<div class="download-widget--title">
|
||||
Download
|
||||
</div>
|
||||
<div data-download-widget-controls style="display: inline-block"></div>
|
||||
</div>
|
||||
<div class="download-widget--body">
|
||||
<p>The recommended way to get started using <code>{{ site.project }}</code> in
|
||||
your project is with a dependency management system – the snippet below can
|
||||
be copied and pasted into your build. Need help? See our getting started guides
|
||||
on building with <a href="https://spring.io/guides/gs/maven/">Maven</a> and
|
||||
<a href="https://spring.io/guides/gs/gradle/">Gradle</a>.
|
||||
</p>
|
||||
<div class="js-download-maven-widget"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,128 @@
|
||||
<head>
|
||||
<title>{{ site.name }}</title>
|
||||
|
||||
<link rel="icon" type="image/png" href="{{site.baseurl}}/favicon.png" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/bootstrap/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Varela+Round|Montserrat:400,700" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/font-awesome/css/font-awesome.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/bootstrap/css/bootstrap-select.css" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/main.css.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/typography.css.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/icons.css.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/projects.css.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/buttons.css.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/guide.css.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/highlight.css.css" />
|
||||
|
||||
{{ head_links }}
|
||||
|
||||
<script src="{{site.baseurl}}/js/jquery.js"></script>
|
||||
<script src="{{site.baseurl}}/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="{{site.baseurl}}/bootstrap/js/bootstrap-select.js"></script>
|
||||
|
||||
<script src="{{site.baseurl}}/js/underscore.js"></script>
|
||||
<script src="{{site.baseurl}}/js/backbone.js"></script>
|
||||
<script src="{{site.baseurl}}/js/projectDocumentationWidget.js"></script>
|
||||
<script src="{{site.baseurl}}/js/application.js"></script>
|
||||
<script src="{{site.baseurl}}/js/clipboard.min.js"></script>
|
||||
<script>
|
||||
var apiBaseUrl = "{{ site.main_site_url }}",
|
||||
projectId = "{{ site.project }}",
|
||||
siteBaseUrl = "{{ site.baseurl }}";
|
||||
</script>
|
||||
<script src="{{site.baseurl}}/js/copySnippets.js"></script>
|
||||
<meta name="google-site-verification" content="7qGntFPD9lWAVCtUu5U77v4l68PsTHf6xpzgjQv2j2M" />
|
||||
<script>
|
||||
var _gaq = _gaq || [];
|
||||
var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';
|
||||
_gaq.push(
|
||||
['_require', 'inpage_linkid', pluginUrl],
|
||||
['_setAccount', 'UA-2728886-22'],
|
||||
['_trackPageview'],
|
||||
['b._require', 'inpage_linkid', pluginUrl],
|
||||
['b._setAccount', 'UA-2728886-19'],
|
||||
['b._trackPageview']
|
||||
);
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
{{ head }}
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="navbar header--navbar">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<div class="spring-logo--container">
|
||||
<a class="spring-logo" href="{{site.main_site_url}}"><span></span></a>
|
||||
</div>
|
||||
<ul class="nav pull-right">
|
||||
<li class="navbar-link"><a href="{{site.main_site_url}}/docs">Docs</a>
|
||||
</li>
|
||||
<li class="navbar-link"><a
|
||||
href="{{site.main_site_url}}/guides">Guides</a></li>
|
||||
<li class="navbar-link active"><a
|
||||
href="{{site.main_site_url}}/projects">Projects</a></li>
|
||||
<li class="navbar-link"><a href="{{site.main_site_url}}/blog">Blog</a>
|
||||
</li>
|
||||
<li class="navbar-link"><a href="{{site.questions_url}}">Questions</a>
|
||||
</li>
|
||||
<li class="navbar-link nav-search"><i
|
||||
class="icon-search navbar-search--icon js-search-input-open"></i>
|
||||
<div class="search-input-close js-search-input-close">x</div></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-dropdown--container js-search-dropdown">
|
||||
<div class="container-fluid">
|
||||
<div class="search-form--container">
|
||||
<form class="form-inline form-search"
|
||||
action="{{site.main_site_url}}/search">
|
||||
<input type="search"
|
||||
class="search-query search-form--form js-search-input"
|
||||
placeholder="Search for documention, guides, and posts..."
|
||||
name="q" />
|
||||
<button class="search-form--submit">
|
||||
<i class="icon-search"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="body--container">{{ content }}</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span8">
|
||||
<div class="navbar">
|
||||
<div class="container">
|
||||
<ul class="nav">
|
||||
<li><a href="{{site.main_site_url}}/team">Team</a></li>
|
||||
<li><a href="{{site.main_site_url}}/services">Services</a></li>
|
||||
<li><a href="{{site.main_site_url}}/tools">Tools</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
© <script> var d = new Date();
|
||||
document.write(d.getFullYear());</script> <a href="https://www.pivotal.io">Pivotal Software</a>, Inc. All Rights Reserved.
|
||||
<a href="https://pivotal.io/terms-of-use">Terms of Use</a> and
|
||||
<a href="https://pivotal.io/privacy-policy">Privacy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div id="scrim"></div>
|
||||
|
||||
{{ end_content }}
|
||||
|
||||
</body>
|
||||
@@ -0,0 +1,24 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>{@= groupId @}</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
<version>{@= version @}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>{@= groupId @}</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
<version>{@= version @}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
{@ if (repository) { @}
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>{@= repository.id @}</id>
|
||||
<name>{@= repository.name @}</name>
|
||||
<url>{@= repository.url @}</url>
|
||||
<snapshots>
|
||||
<enabled>{@= repository.snapshotsEnabled @}</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>{@ } @}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="project--container">
|
||||
<a href="{{include.site_url}}">
|
||||
<div class="project--title">{{include.project_title}}</div>
|
||||
<p class="project--description">{{include.project_description}}</p>
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
{% capture content %}
|
||||
{% include billboard.html %}
|
||||
<div class="project-body--wrapper">
|
||||
<div class="project-body--container">
|
||||
<div class="projects--wrapper project-aggregator">
|
||||
{{ main_content | markdownify }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endcapture %}
|
||||
{% include page.html %}
|
||||
@@ -0,0 +1,29 @@
|
||||
{% capture billboard_quickstart_button %}
|
||||
<a class="btn btn-black uppercase project-quickstart-btn" href="#quick-start">Quick Start</a>
|
||||
{% endcapture %}
|
||||
{% capture content %}
|
||||
{% include billboard.html %}
|
||||
<div class="github-fork-ribbon--container">
|
||||
<a href="{{ site.github_repo_url }}"><img style="position: absolute; top: 0; right: 0; border: 0;" src="{{site.baseurl}}/img/forkme.png" alt="Fork me on GitHub"></a>
|
||||
</div>
|
||||
<div class="project-body--wrapper">
|
||||
<div class="project-body--container">
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span8">
|
||||
<div class="project-body--section">
|
||||
{{ main_content | markdownify }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="span4">
|
||||
{% include project_sidebar.html %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endcapture %}
|
||||
{% capture end_content %}
|
||||
{% include widget_templates.html %}
|
||||
{% endcapture %}
|
||||
{% include page.html %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% include documentation.html %}
|
||||
<div class="right-pane-widget--container no-top-border">
|
||||
<div class="project-sub-link--wrapper">
|
||||
{% include badges.html %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-pane-widget--container no-top-border project-sidebar-resource--wrapper">
|
||||
{{ related_resources | markdownify }}
|
||||
</div>
|
||||
@@ -0,0 +1,136 @@
|
||||
<script type="text/html" id="project-documentation-widget-template">
|
||||
<div class="right-pane-widget--container no-top-border project-documentation--container">
|
||||
<div class="item-dropdown-widget">
|
||||
<div class="item-dropdown--title">{@= name @}</div>
|
||||
<div class="item--dropdown">
|
||||
<div class="item--body">
|
||||
<div class="item--body-title">
|
||||
<div class="item--left-column">Release</div>
|
||||
<div class="item--right-column">Documentation</div>
|
||||
</div>
|
||||
{@ _.each(releases, function(release) { @}
|
||||
<div class="item--body--version">
|
||||
<div class="item--left-column">
|
||||
<p>{@= release.versionDisplayName @}</p>
|
||||
{@ if(release.current) { @}
|
||||
<div class="spring-icon spring-icon-current-version"></div>
|
||||
{@ } @}
|
||||
<div class="spring-icon {@= release.statusIconClass() @}"></div>
|
||||
</div>
|
||||
<div class="item--right-column">
|
||||
{@ if (release.refDocUrl !== '') { @}
|
||||
<a href='{@= release.refDocUrl @}' class="docs-link reference-link">Reference</a>
|
||||
{@ }; @}
|
||||
{@ if (release.apiDocUrl !== '') { @}
|
||||
<a href='{@= release.apiDocUrl @}' class="docs-link api-link">API</a>
|
||||
{@ }; @}
|
||||
</div>
|
||||
</div>
|
||||
{@ }); @}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="project-download-widget-controls-template">
|
||||
<div class="js-download-widget-selector">
|
||||
<select class='selector selectpicker'>
|
||||
{@ _.each(releases, function(release, index) { @}
|
||||
<option value="{@= index @}"
|
||||
data-content="
|
||||
<span>{@= release.versionDisplayName @}</span>
|
||||
{@ if(release.current) { @}
|
||||
<div class='spring-icon spring-icon-current-version'></div>
|
||||
{@ } @}
|
||||
<div class='spring-icon {@= release.statusIconClass() @}'/>"
|
||||
data-current="{@= release.current @}">
|
||||
()
|
||||
</option>
|
||||
{@ }); @}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="item-slider-widget js-item-slider--wrapper">
|
||||
<div class="item-slider--container">
|
||||
<div class="item--slider js-item--slider"></div>
|
||||
<div class="item js-active js-item" data-snippet-type='maven'>
|
||||
Maven
|
||||
</div>
|
||||
<div class="item js-item" data-snippet-type='gradle'>
|
||||
Gradle
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
{% if site.custom_pom_template %}
|
||||
{% capture maven_pom_template %}
|
||||
{% include pom.xml %}
|
||||
{% endcapture %}
|
||||
{% else %}
|
||||
{% capture maven_pom_template %}
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>{@= groupId @}</groupId>
|
||||
<artifactId>{@= artifactId @}</artifactId>
|
||||
<version>{@= version @}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
<script type="text/html" id="project-download-maven-widget-template">
|
||||
{% highlight xml %}
|
||||
{{ maven_pom_template }}
|
||||
{% endhighlight %}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="project-repository-maven-widget-template">
|
||||
{% highlight xml %}
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>{@= repository.id @}</id>
|
||||
<name>{@= repository.name @}</name>
|
||||
<url>{@= repository.url @}</url>
|
||||
<snapshots>
|
||||
<enabled>{@= repository.snapshotsEnabled @}</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
{% endhighlight %}
|
||||
</script>
|
||||
|
||||
{% if site.custom_gradle_template %}
|
||||
{% capture gradle_template %}
|
||||
{% include build.gradle %}
|
||||
{% endcapture %}
|
||||
{% else %}
|
||||
{% capture gradle_template %}
|
||||
dependencies {
|
||||
compile '{@= groupId @}:{@= artifactId @}:{@= version @}'
|
||||
}
|
||||
{% endcapture %}
|
||||
{% endif %}
|
||||
|
||||
<script type="text/html" id="project-download-gradle-widget-template">
|
||||
{% highlight groovy %}
|
||||
{{ gradle_template }}
|
||||
{% endhighlight %}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="project-repository-gradle-widget-template">
|
||||
{% highlight groovy %}
|
||||
repositories {
|
||||
maven {
|
||||
url '{@= repository.url @}'
|
||||
}
|
||||
}
|
||||
{% endhighlight %}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="project-download-zip-widget-template">
|
||||
This is a zip url
|
||||
</script>
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
---
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
|
||||
{% capture head_links %}
|
||||
<link rel="stylesheet" type="text/css" href="{{site.baseurl}}/css/documentation.css" />
|
||||
{% endcapture %}
|
||||
|
||||
{% capture content %}
|
||||
<div class="project-body--wrapper" id="quick-start">
|
||||
<div class="project-body--container">
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div class="project-body--section">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
|
||||
{% include page.html %}
|
||||
</html>
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
layout: documentation_page
|
||||
---
|
||||
|
||||
# My Project ReadMe
|
||||
This would be taken from the project
|
||||
|
||||
|
||||
## Sub Heading
|
||||
Birth, a very small stage in a vast cosmic
|
||||
arena extraordinary claims require extraordinary evidence! Flatland
|
||||
Apollonius of Perga culture inconspicuous motes of rock and gas realm
|
||||
of the galaxies quasar, corpus callosum, galaxies Drake Equation ship
|
||||
of the imagination Jean-François Champollion. Galaxies Hypatia!
|
||||
Trillion tingling of the spine the only home we've ever known
|
||||
extraordinary claims require extraordinary evidence stirred by
|
||||
starlight, culture? Flatland Tunguska event finite but unbounded
|
||||
corpus callosum!
|
||||
|
||||
Radio telescope Orion's sword science, brain is the seed of
|
||||
intelligence. Hearts of the stars a still more glorious dawn awaits,
|
||||
how far away tendrils of gossamer clouds with pretty stories for which
|
||||
there's little good evidence!
|
||||
|
||||
Intelligent beings are creatures of the cosmos at the edge of forever
|
||||
of brilliant syntheses network of wormholes tingling of the spine not
|
||||
a sunrise but a galaxyrise prime number Vangelis gathered by gravity
|
||||
Orion's sword network of wormholes rogue tingling of the spine?
|
||||
|
||||
```java
|
||||
public static void main() {
|
||||
// long long long long long long long long long long long long long long long long long long long long long long long
|
||||
}
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
* Implementation of CRUD methods for JPA Entities
|
||||
* Dynamic query generation from query method names
|
||||
* Transparent triggering of JPA NamedQueries by query methods
|
||||
* Implementation domain base classes providing basic properties
|
||||
* Support for transparent auditing (created, last changed)
|
||||
* Possibility to integrate custom repository code
|
||||
* Easy Spring integration with custom namespace
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
# The name of your project
|
||||
title: Spring Data JPA
|
||||
|
||||
badges:
|
||||
|
||||
# Specify your project's twitter handle, if any. Delete if none.
|
||||
twitter: SpringData
|
||||
|
||||
# Customize your project's badges. Delete any entries that do not apply.
|
||||
custom:
|
||||
- name: Source (GitHub)
|
||||
url: https://github.com/spring-projects/spring-data-jpa
|
||||
icon: github
|
||||
|
||||
- name: Issues (JIRA)
|
||||
url: https://jira.springsource.org/browse/DATAJPA
|
||||
icon: tracking
|
||||
|
||||
- name: CI (Bamboo)
|
||||
url: https://build.springsource.org/browse/SPRINGDATAJPA
|
||||
icon: ci
|
||||
|
||||
- name: Forum
|
||||
url: https://forum.spring.io/forum/spring-projects/data
|
||||
icon: forum
|
||||
|
||||
- name: StackOverflow
|
||||
url: https://stackoverflow.com/questions/tagged/spring-data-jpa
|
||||
icon: stackoverflow
|
||||
|
||||
- name: Metrics (SonarQube)
|
||||
url: https://sonar.springsource.org/dashboard/index/org.springframework.data:spring-data-jpa
|
||||
icon: metrics
|
||||
|
||||
---
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
|
||||
<!-- Specify the parent of this project (or delete if none) to influence the rendering of the breadcrumb -->
|
||||
{% capture parent_link %}
|
||||
[Spring Parent]({{ site.projects_site_url }}/spring-parent)
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
{% capture billboard_description %}
|
||||
|
||||
**PROJECT DESCRIPTION** Corpus callosum,
|
||||
[the carbon](#) in our apple pies a mote of dust suspended in a
|
||||
sunbeam. Muse about! Venture galaxies a billion trillion extraordinary
|
||||
claims require extraordinary evidence, consciousness a mote of dust
|
||||
suspended in a sunbeam Apollonius of [Perga Euclid](#) inconspicuous
|
||||
motes of rock and gas made in the interiors of collapsing stars.
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% capture main_content %}
|
||||
|
||||
**INTRODUCTORY PARAGRAPHS** Birth, a very small stage in a vast cosmic
|
||||
arena extraordinary claims require extraordinary evidence! Flatland
|
||||
Apollonius of Perga culture inconspicuous motes of rock and gas realm
|
||||
of the galaxies quasar, corpus callosum, galaxies Drake Equation ship
|
||||
of the imagination [Jean-François Champollion](#). Galaxies Hypatia!
|
||||
Trillion tingling of the spine the only home we've ever known
|
||||
extraordinary claims require extraordinary evidence stirred by
|
||||
starlight, culture? Flatland Tunguska event finite but unbounded
|
||||
corpus callosum!
|
||||
|
||||
## Features
|
||||
|
||||
* Feature 1
|
||||
* [Feature 2](#)
|
||||
* Feature 3
|
||||
* Feature 4
|
||||
* ...
|
||||
|
||||
<span id="quick-start"></span>
|
||||
|
||||
## Quick Start
|
||||
|
||||
{% include download_widget.md %}
|
||||
|
||||
|
||||
```java
|
||||
package foo;
|
||||
|
||||
import foo;
|
||||
|
||||
public class SearchController {
|
||||
|
||||
@Foo
|
||||
public SearchController(SearchService searchService) {
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// This is just a test to see how a very long line works with our project css
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% capture related_resources %}
|
||||
|
||||
### Sample Projects
|
||||
|
||||
* [Project Name 1](#)
|
||||
* [Project name 2](#)
|
||||
* [Project name nth](#)
|
||||
|
||||
### Getting Started Guides
|
||||
|
||||
* [GSG 1]({{site.main_site_url}}/guides/gs/rest-service)
|
||||
* [GSG 2]({{site.main_site_url}}/guides/gs/other-guide-2)
|
||||
* [GSG n]({{site.main_site_url}}/guides/gs/other-guide-3)
|
||||
|
||||
### Tutorials
|
||||
|
||||
* [Tutorial 1]({{site.main_site_url}}/guides/tutorials/rest)
|
||||
* [Tutorial 2]({{site.main_site_url}}/guides/tutorials/other-2)
|
||||
* [Tutorial n]({{site.main_site_url}}/guides/tutorials/other-3)
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
|
||||
{% include project_page.html %}
|
||||
</html>
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
---
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
{% capture billboard_description %}
|
||||
Spring Data makes it easier to build Spring-powered applications that use new data access
|
||||
technologies such as non-relational databases, map-reduce frameworks, and cloud based data services
|
||||
as well as provide improved support for relational database technologies.
|
||||
Spring Data is an umbrella open source project which contains many subprojects that are specific
|
||||
to a given database. The projects are developed by working together with many of the companies
|
||||
and developers that are behind these exciting technologies.
|
||||
{% endcapture %}
|
||||
|
||||
{% capture main_content %}
|
||||
|
||||
{% capture project_description %}
|
||||
Hearts of the stars brain is the seed of intelligence consciousness extraplanetary shores of the cosmic ocean! As a patch of light paroxysm of global death? Inconspicuous motes of rock and gas.
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/sprinframework" project_title="Spring Framework" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
This is Apache Hadoop Hadoop!
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/spring_hadoop" project_title="Apache Hadoop" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
Hearts of the stars brain is the seed of intelligence consciousness extraplanetary shores of the cosmic ocean! As a patch of light paroxysm of global death? Inconspicuous motes of rock and gas.
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/sprinframework" project_title="Spring Framework" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
This is Apache Hadoop Hadoop!
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/spring_hadoop" project_title="Apache Hadoop" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
Hearts of the stars brain is the seed of intelligence consciousness extraplanetary shores of the cosmic ocean! As a patch of light paroxysm of global death? Inconspicuous motes of rock and gas.
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/sprinframework" project_title="Spring Framework" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
This is Apache Hadoop Hadoop!
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/spring_hadoop" project_title="Apache Hadoop" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
Hearts of the stars brain is the seed of intelligence consciousness extraplanetary shores of the cosmic ocean! As a patch of light paroxysm of global death? Inconspicuous motes of rock and gas.
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/sprinframework" project_title="Spring Framework" project_description=project_description %}
|
||||
|
||||
{% capture project_description %}
|
||||
This is Apache Hadoop Hadoop!
|
||||
{% endcapture %}
|
||||
{% include project_block.md site_url="https://www.spring.io" repo_url="https://github.com/spring_hadoop" project_title="Apache Hadoop" project_description=project_description %}
|
||||
|
||||
{% endcapture %}
|
||||
|
||||
{% include project_group_page.html %}
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
layout: default
|
||||
title: Page Title Here
|
||||
---
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
**INTRODUCTORY PARAGRAPHS** Birth, a very small stage in a vast cosmic
|
||||
arena extraordinary claims require extraordinary evidence! Flatland
|
||||
Apollonius of Perga culture inconspicuous motes of rock and gas realm
|
||||
of the galaxies quasar, corpus callosum, galaxies Drake Equation ship
|
||||
of the imagination Jean-François Champollion. Galaxies Hypatia!
|
||||
Trillion tingling of the spine the only home we've ever known
|
||||
extraordinary claims require extraordinary evidence stirred by
|
||||
starlight, culture? Flatland Tunguska event finite but unbounded
|
||||
corpus callosum!
|
||||
|
||||
Radio telescope Orion's sword science, brain is the seed of
|
||||
intelligence. Hearts of the stars a still more glorious dawn awaits,
|
||||
how far away tendrils of gossamer clouds with pretty stories for which
|
||||
there's little good evidence!
|
||||
|
||||
Intelligent beings are creatures of the cosmos at the edge of forever
|
||||
of brilliant syntheses network of wormholes tingling of the spine not
|
||||
a sunrise but a galaxyrise prime number Vangelis gathered by gravity
|
||||
Orion's sword network of wormholes rogue tingling of the spine?
|
||||
|
||||
## Features
|
||||
|
||||
* Implementation of CRUD methods for JPA Entities
|
||||
* Dynamic query generation from query method names
|
||||
* Transparent triggering of JPA NamedQueries by query methods
|
||||
* Implementation domain base classes providing basic properties
|
||||
* Support for transparent auditing (created, last changed)
|
||||
* Possibility to integrate custom repository code
|
||||
* Easy Spring integration with custom namespace
|
||||
</html>
|
||||
@@ -1,205 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright 2001-2004 The Apache Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
http://checkstyle.sf.net (or in your downloaded distribution).
|
||||
|
||||
Most Checks are configurable, be sure to consult the documentation.
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
|
||||
Finally, it is worth reading the documentation.
|
||||
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
|
||||
<!-- Checks that a package.html file exists for each package. -->
|
||||
<!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
|
||||
<!-- module name="PackageHtml"/ -->
|
||||
|
||||
<!-- Checks whether files end with a new line. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- Checks that property files contain the same keys. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
|
||||
<module name="Translation"/>
|
||||
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<property name="cacheFile" value="${checkstyle.cache.file}"/>
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
|
||||
<!--
|
||||
<module name="JavadocMethod"/>
|
||||
<module name="JavadocType"/>
|
||||
<module name="JavadocVariable"/>
|
||||
<module name="JavadocStyle"/>
|
||||
-->
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See http://checkstyle.sf.net/config_naming.html -->
|
||||
<module name="ConstantName">
|
||||
<!-- logger variables break normal constant syntax. We need to allow lower case too -->
|
||||
<property name="format" value="^[a-zA-Z][a-zA-Z0-9]*(_[A-Z0-9]+)*$"/>
|
||||
</module>
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="MemberName"/>
|
||||
<module name="MethodName"/>
|
||||
<module name="PackageName"/>
|
||||
<module name="ParameterName"/>
|
||||
<module name="StaticVariableName"/>
|
||||
<module name="TypeName"/>
|
||||
|
||||
|
||||
<!-- Checks for Headers -->
|
||||
<!-- See http://checkstyle.sf.net/config_header.html -->
|
||||
<!-- <module name="Header"> -->
|
||||
<!-- The follow property value demonstrates the ability -->
|
||||
<!-- to have access to ANT properties. In this case it uses -->
|
||||
<!-- the ${basedir} property to allow Checkstyle to be run -->
|
||||
<!-- from any directory within a project. See property -->
|
||||
<!-- expansion, -->
|
||||
<!-- http://checkstyle.sf.net/config.html#properties -->
|
||||
<!-- <property -->
|
||||
<!-- name="headerFile" -->
|
||||
<!-- value="${basedir}/java.header"/> -->
|
||||
<!-- </module> -->
|
||||
|
||||
<!-- Following interprets the header file as regular expressions. -->
|
||||
<!-- <module name="RegexpHeader"/> -->
|
||||
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See http://checkstyle.sf.net/config_imports.html -->
|
||||
<module name="AvoidStarImport">
|
||||
<property name="excludes" value="javax.servlet,java.util"/>
|
||||
</module>
|
||||
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
|
||||
<module name="RedundantImport"/>
|
||||
<!--module name="UnusedImports"/ -->
|
||||
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sf.net/config_sizes.html -->
|
||||
<module name="FileLength"/>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="125"/>
|
||||
</module>
|
||||
<module name="MethodLength"/>
|
||||
<module name="ParameterNumber"/>
|
||||
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="NoWhitespaceAfter"/>
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="TabCharacter"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<!--
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyMethods" value="true"/>
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
</module>
|
||||
-->
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See http://checkstyle.sf.net/config_blocks.html -->
|
||||
<module name="AvoidNestedBlocks"/>
|
||||
<!-- module name="EmptyBlock"/ -->
|
||||
<module name="LeftCurly"/>
|
||||
<module name="NeedBraces"/>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See http://checkstyle.sf.net/config_coding.html -->
|
||||
<!-- module name="AvoidInlineConditionals"/ -->
|
||||
<module name="DoubleCheckedLocking"/> <!-- MY FAVOURITE -->
|
||||
<module name="EmptyStatement"/>
|
||||
<!-- module name="EqualsHashCode"/ -->
|
||||
<!--
|
||||
<module name="HiddenField">
|
||||
<property name="ignoreConstructorParameter" value="true"/>
|
||||
<property name="ignoreSetter" value="true"/>
|
||||
</module>
|
||||
-->
|
||||
<module name="IllegalInstantiation"/>
|
||||
<module name="InnerAssignment"/>
|
||||
<!-- module name="MagicNumber"/ -->
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<!--
|
||||
<module name="RedundantThrows">
|
||||
<property name="allowUnchecked" value="true"/>
|
||||
</module>
|
||||
-->
|
||||
<!--
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
-->
|
||||
<!-- Checks for class design -->
|
||||
<!-- See http://checkstyle.sf.net/config_design.html -->
|
||||
<!-- module name="DesignForExtension"/ -->
|
||||
<module name="FinalClass"/>
|
||||
<module name="HideUtilityClassConstructor"/>
|
||||
<module name="InterfaceIsType"/>
|
||||
<module name="VisibilityModifier">
|
||||
<!-- logger variables are often protected -->
|
||||
<property name="protectedAllowed" value="true"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<!-- module name="FinalParameters"/ -->
|
||||
<!--
|
||||
<module name="GenericIllegalRegexp">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="message" value="Line has trailing spaces."/>
|
||||
</module>
|
||||
-->
|
||||
<!-- module name="TrailingComment"/ -->
|
||||
<!-- module name="TodoComment"/ -->
|
||||
<module name="UpperEll"/>
|
||||
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -1 +0,0 @@
|
||||
target
|
||||
@@ -1,5 +0,0 @@
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
.wtpmodules
|
||||
@@ -1,26 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-cas</artifactId>
|
||||
<name>Acegi Security System for Spring - CAS adapter</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cas</groupId>
|
||||
<artifactId>cas-server</artifactId>
|
||||
<version>3.0.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cas</groupId>
|
||||
<artifactId>cas</artifactId>
|
||||
<version>2.0.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,102 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.cas;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Provides actual CAS authentication by delegation to an <code>AuthenticationManager</code>.<P>Do not use this
|
||||
* class directly. Instead configure CAS to use the {@link CasPasswordHandlerProxy}.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class CasPasswordHandler implements InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CasPasswordHandler.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.authenticationManager == null) {
|
||||
throw new IllegalArgumentException("An AuthenticationManager is required");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>CasPasswordHandlerProxy</code> for individual authentication requests.<P>Delegates to
|
||||
* the configured <code>AuthenticationManager</code>.</p>
|
||||
*
|
||||
* @param servletRequest as provided by CAS
|
||||
* @param username provided to CAS
|
||||
* @param password provided to CAS
|
||||
*
|
||||
* @return whether authentication was successful or not
|
||||
*/
|
||||
public boolean authenticate(ServletRequest servletRequest, String username, String password) {
|
||||
if ((username == null) || "".equals(username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
Authentication request = new UsernamePasswordAuthenticationToken(username.toString(), password.toString());
|
||||
Authentication response = null;
|
||||
|
||||
try {
|
||||
response = authenticationManager.authenticate(request);
|
||||
} catch (AuthenticationException failed) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " successful");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public AuthenticationManager getAuthenticationManager() {
|
||||
return authenticationManager;
|
||||
}
|
||||
|
||||
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.cas;
|
||||
|
||||
import edu.yale.its.tp.cas.auth.PasswordHandler;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Enables CAS to use the Acegi Security System for authentication.<P>This class works along with {@link
|
||||
* CasPasswordHandler} to enable users to easily migrate from stand-alone Acegi Security System deployments to
|
||||
* enterprise-wide CAS deployments.</p>
|
||||
* <p>It should be noted that the Acegi Security System will operate as a CAS client irrespective of the
|
||||
* <code>PasswordHandler</code> used on the CAS server. In other words, this class need <B>not</B> be used on the CAS
|
||||
* server if not desired. It exists solely for the convenience of users wishing have CAS delegate to an Acegi Security
|
||||
* System-based <code>AuthenticationManager</code>.</p>
|
||||
* <p>This class works requires a properly configured <code>CasPasswordHandler</code>. On the first authentication
|
||||
* request, the class will use Spring's {@link WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)}
|
||||
* method to obtain an <code>ApplicationContext</code> instance, inside which must be a configured
|
||||
* <code>CasPasswordHandler</code> instance. The <code>CasPasswordHandlerProxy</code> will then delegate
|
||||
* authentication requests to that instance.</p>
|
||||
* <p>To configure CAS to use this class, edit CAS' <code>web.xml</code> and define the
|
||||
* <code>edu.yale.its.tp.cas.authHandler</code> context parameter with the value
|
||||
* <code>org.acegisecurity.adapters.cas.CasPasswordHandlerProxy</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasPasswordHandlerProxy implements PasswordHandler {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CasPasswordHandlerProxy.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private ApplicationContext ctx;
|
||||
private CasPasswordHandler handler;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Called by CAS when authentication is required.<P>Delegates to the <code>CasPasswordHandler</code>.</p>
|
||||
*
|
||||
* @param request as provided by CAS
|
||||
* @param username provided to CAS
|
||||
* @param password provided to CAS
|
||||
*
|
||||
* @return whether authentication was successful or not
|
||||
*
|
||||
* @throws IllegalArgumentException if the application context does not contain a <code>CasPasswordHandler</code>
|
||||
* or the <code>ServletRequest</code> was not of type <code>HttpServletRequest</code>
|
||||
*/
|
||||
public boolean authenticate(ServletRequest request, String username, String password) {
|
||||
if (ctx == null) {
|
||||
if (!(request instanceof HttpServletRequest)) {
|
||||
throw new IllegalArgumentException("Can only process HttpServletRequest");
|
||||
}
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
|
||||
ctx = this.getContext(httpRequest);
|
||||
}
|
||||
|
||||
if (handler == null) {
|
||||
Map beans = ctx.getBeansOfType(CasPasswordHandler.class, true, true);
|
||||
|
||||
if (beans.size() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Bean context must contain at least one bean of type CasPasswordHandler");
|
||||
}
|
||||
|
||||
String beanName = (String) beans.keySet().iterator().next();
|
||||
handler = (CasPasswordHandler) beans.get(beanName);
|
||||
}
|
||||
|
||||
return handler.authenticate(request, username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows test cases to override where application context obtained from.
|
||||
*
|
||||
* @param httpRequest which can be used to find the <code>ServletContext</code>
|
||||
*
|
||||
* @return the Spring application context
|
||||
*/
|
||||
protected ApplicationContext getContext(HttpServletRequest httpRequest) {
|
||||
return WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession().getServletContext());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Adapter to Yale Central Authentication Service (CAS).
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.cas3;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.jasig.cas.authentication.handler.AuthenticationException;
|
||||
import org.jasig.cas.authentication.handler.AuthenticationHandler;
|
||||
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
|
||||
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Provides JA-SIG CAS 3 authentication by delegating to the Acegi <code>AuthenticationManager</code>.</p>
|
||||
* <p>This class would be configured in the <code>webapp/WEB-INF/deployerConfigContext.xml</code> file in the CAS
|
||||
* distribution.</p>
|
||||
*
|
||||
* @author Scott Battaglia
|
||||
* @version $Id$
|
||||
*
|
||||
* @see AuthenticationHandler
|
||||
* @see AuthenticationManager
|
||||
*/
|
||||
public final class CasAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
private Log log = LogFactory.getLog(this.getClass());
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void afterPropertiesSetInternal() throws Exception {
|
||||
Assert.notNull(this.authenticationManager, "authenticationManager cannot be null.");
|
||||
}
|
||||
|
||||
protected boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials)
|
||||
throws AuthenticationException {
|
||||
final Authentication authenticationRequest = new UsernamePasswordAuthenticationToken(credentials.getUsername(),
|
||||
credentials.getPassword());
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Attempting to authenticate for user: " + credentials.getUsername());
|
||||
}
|
||||
|
||||
try {
|
||||
this.authenticationManager.authenticate(authenticationRequest);
|
||||
} catch (final org.acegisecurity.AuthenticationException e) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Authentication request for " + credentials.getUsername() + " failed: " + e.toString(), e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Authentication request for " + credentials.getUsername() + " successful.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set the Acegi <code>AuthenticationManager</code> to delegate to.
|
||||
*
|
||||
* @param authenticationManager the Acegi AuthenticationManager that knows how to authenticate users.
|
||||
*/
|
||||
public void setAuthenticationManager(final AuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<!--
|
||||
* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Demonstration of the applicationContext.xml that should be placed in
|
||||
* CAS' WEB-INF directory. Note the CasPasswordHandler bean.
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- Data access object which stores authentication information -->
|
||||
<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
||||
<property name="userMap">
|
||||
<value>
|
||||
marissa=koala,ROLES_IGNORED_BY_CAS
|
||||
dianne=emu,ROLES_IGNORED_BY_CAS
|
||||
scott=wombat,ROLES_IGNORED_BY_CAS
|
||||
peter=opal,disabled,ROLES_IGNORED_BY_CAS
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService"><ref bean="inMemoryDaoImpl"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref bean="daoAuthenticationProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="casPasswordHandler" class="org.acegisecurity.adapters.cas.CasPasswordHandler">
|
||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
</bean>
|
||||
</beans>
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<!--
|
||||
* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Demonstration of the applicationContext.xml that should be copied into
|
||||
* JA-SIG CAS's webapp/WEB-INF/deployerConfigContext.xml
|
||||
* The example CAS AuthenticationHandler should be placed within CAS's
|
||||
* AuthenticationManager's authenticationHandler list property.
|
||||
*
|
||||
* The Acegi-specific beans can just be placed in the context file.
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<beans>
|
||||
|
||||
<!-- Data access object which stores authentication information -->
|
||||
<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
||||
<property name="userMap">
|
||||
<value>
|
||||
marissa=koala,ROLES_IGNORED_BY_CAS
|
||||
dianne=emu,ROLES_IGNORED_BY_CAS
|
||||
scott=wombat,ROLES_IGNORED_BY_CAS
|
||||
peter=opal,disabled,ROLES_IGNORED_BY_CAS
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService"><ref bean="inMemoryDaoImpl"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref bean="daoAuthenticationProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="casAuthenticationHandler" class="org.acegisecurity.adapters.cas3.CasAuthenticationHandler">
|
||||
<property name="authenticationManager" ref="authenticationManager" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<project name="Acegi Security CAS Adapter">
|
||||
<body>
|
||||
<menu ref="parent"/>
|
||||
<menu ref="reports"/>
|
||||
</body>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasPasswordHandlerProxy}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasPasswordHandlerProxyTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CasPasswordHandlerProxyTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasPasswordHandlerProxyTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasPasswordHandlerProxyTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testDetectsIfHttpServletRequestNotPassed() {
|
||||
CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy(
|
||||
"org/acegisecurity/adapters/cas/applicationContext-valid.xml");
|
||||
|
||||
try {
|
||||
proxy.authenticate(null, "x", "y");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Can only process HttpServletRequest", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingDelegate() {
|
||||
CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy(
|
||||
"org/acegisecurity/adapters/cas/applicationContext-invalid.xml");
|
||||
|
||||
try {
|
||||
proxy.authenticate(new MockHttpServletRequest(), "x", "y");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Bean context must contain at least one bean of type CasPasswordHandler", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testNormalOperation() {
|
||||
CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy(
|
||||
"org/acegisecurity/adapters/cas/applicationContext-valid.xml");
|
||||
assertTrue(proxy.authenticate(new MockHttpServletRequest(), "marissa", "koala"));
|
||||
assertFalse(proxy.authenticate(new MockHttpServletRequest(), "marissa", "WRONG_PASSWORD"));
|
||||
assertFalse(proxy.authenticate(new MockHttpServletRequest(), "INVALID_USER_NAME", "WRONG_PASSWORD"));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
/**
|
||||
* Mock object so that application context source can be specified.
|
||||
*/
|
||||
private class MockCasPasswordHandlerProxy extends CasPasswordHandlerProxy {
|
||||
private ApplicationContext ctx;
|
||||
|
||||
public MockCasPasswordHandlerProxy(String appContextLocation) {
|
||||
ctx = new ClassPathXmlApplicationContext(appContextLocation);
|
||||
}
|
||||
|
||||
private MockCasPasswordHandlerProxy() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected ApplicationContext getContext(HttpServletRequest httpRequest) {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.MockAuthenticationManager;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasPasswordHandler}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasPasswordHandlerTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CasPasswordHandlerTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasPasswordHandlerTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasPasswordHandlerTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testDeniesAccessWhenAuthenticationManagerThrowsException()
|
||||
throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(false));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
assertFalse(handler.authenticate(new MockHttpServletRequest(), "username", "password"));
|
||||
}
|
||||
|
||||
public void testDetectsEmptyAuthenticationManager()
|
||||
throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
|
||||
try {
|
||||
handler.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("An AuthenticationManager is required", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(false));
|
||||
assertTrue(handler.getAuthenticationManager() != null);
|
||||
}
|
||||
|
||||
public void testGracefullyHandlesEmptyUsernamesAndPassword()
|
||||
throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
// If empty or null username we return false
|
||||
assertFalse(handler.authenticate(new MockHttpServletRequest(), "", "password"));
|
||||
assertFalse(handler.authenticate(new MockHttpServletRequest(), null, "password"));
|
||||
|
||||
// We authenticate with null passwords (they might not have one)
|
||||
assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", null));
|
||||
assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", ""));
|
||||
}
|
||||
|
||||
public void testNormalOperation() throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
assertTrue(handler.authenticate(new MockHttpServletRequest(), "username", "password"));
|
||||
}
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.cas3;
|
||||
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.jasig.cas.authentication.handler.AuthenticationException;
|
||||
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
|
||||
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasAuthenticationHandler}
|
||||
*
|
||||
* @author Scott Battaglia
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasAuthenticationHandlerTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
private CasAuthenticationHandler casAuthenticationHandler;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
return new String[] {"/org/acegisecurity/adapters/cas/applicationContext-valid.xml"};
|
||||
}
|
||||
|
||||
private UsernamePasswordCredentials getCredentialsFor(final String username, final String password) {
|
||||
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials();
|
||||
credentials.setUsername(username);
|
||||
credentials.setPassword(password);
|
||||
|
||||
return credentials;
|
||||
}
|
||||
|
||||
protected void onSetUp() throws Exception {
|
||||
this.casAuthenticationHandler = new CasAuthenticationHandler();
|
||||
this.casAuthenticationHandler.setAuthenticationManager(authenticationManager);
|
||||
this.casAuthenticationHandler.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void setAuthenticationManager(final AuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
this.casAuthenticationHandler.setAuthenticationManager(null);
|
||||
|
||||
try {
|
||||
this.casAuthenticationHandler.afterPropertiesSet();
|
||||
fail("IllegalArgumenException expected when no AuthenticationManager is set.");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
// this is okay
|
||||
}
|
||||
}
|
||||
|
||||
public void testGracefullyHandlesInvalidInput() {
|
||||
try {
|
||||
assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor("", "")));
|
||||
assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor(null, null)));
|
||||
} catch (final AuthenticationException e) {
|
||||
fail("AuthenticationException not expected.");
|
||||
}
|
||||
}
|
||||
|
||||
public void testInvalidUsernamePasswordCombination() {
|
||||
try {
|
||||
assertFalse(this.casAuthenticationHandler.authenticate(getCredentialsFor("scott", "scott")));
|
||||
} catch (final AuthenticationException e) {
|
||||
fail("AuthenticationException not expected.");
|
||||
}
|
||||
}
|
||||
|
||||
public void testValidUsernamePasswordCombination() {
|
||||
try {
|
||||
assertTrue(this.casAuthenticationHandler.authenticate(getCredentialsFor("scott", "wombat")));
|
||||
} catch (final AuthenticationException e) {
|
||||
fail("AuthenticationException not expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<!--
|
||||
* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
||||
<property name="userMap">
|
||||
<value>
|
||||
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
|
||||
dianne=emu,ROLE_TELLER
|
||||
scott=wombat,ROLE_TELLER
|
||||
peter=opal,disabled,ROLE_TELLER
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService"><ref bean="inMemoryDaoImpl"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref bean="daoAuthenticationProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- No CasPasswordHandler -->
|
||||
</beans>
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<!--
|
||||
* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
||||
<property name="userMap">
|
||||
<value>
|
||||
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
|
||||
dianne=emu,ROLE_TELLER
|
||||
scott=wombat,ROLE_TELLER
|
||||
peter=opal,disabled,ROLE_TELLER
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService"><ref bean="inMemoryDaoImpl"/></property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref bean="daoAuthenticationProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="casPasswordHandler" class="org.acegisecurity.adapters.cas.CasPasswordHandler">
|
||||
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,5 +0,0 @@
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
.wtpmodules
|
||||
@@ -1,17 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-catalina</artifactId>
|
||||
<name>Acegi Security System for Spring - Catalina adapter</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>tomcat</groupId>
|
||||
<artifactId>catalina</artifactId>
|
||||
<version>4.1.9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-236
@@ -1,236 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.catalina;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.apache.catalina.Container;
|
||||
import org.apache.catalina.LifecycleException;
|
||||
import org.apache.catalina.realm.RealmBase;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.support.FileSystemXmlApplicationContext;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to enable Catalina (Tomcat) to authenticate via the Acegi Security System for Spring.<p>Returns a {@link
|
||||
* PrincipalAcegiUserToken} to Catalina's authentication system, which is subsequently available via
|
||||
* <code>HttpServletRequest.getUserPrincipal()</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CatalinaAcegiUserRealm extends RealmBase {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CatalinaAcegiUserRealm.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
private Container container;
|
||||
private String appContextLocation;
|
||||
private String key;
|
||||
protected final String name = "CatalinaSpringUserRealm / $Id$";
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Principal authenticate(String username, String credentials) {
|
||||
if (username == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (credentials == null) {
|
||||
credentials = "";
|
||||
}
|
||||
|
||||
Authentication request = new UsernamePasswordAuthenticationToken(username, credentials);
|
||||
Authentication response = null;
|
||||
|
||||
try {
|
||||
response = authenticationManager.authenticate(request);
|
||||
} catch (AuthenticationException failed) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PrincipalAcegiUserToken(this.key, response.getPrincipal().toString(),
|
||||
response.getCredentials().toString(), response.getAuthorities(), response.getPrincipal());
|
||||
}
|
||||
|
||||
public Principal authenticate(String username, byte[] credentials) {
|
||||
return authenticate(username, new String(credentials));
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported, returns null
|
||||
*
|
||||
* @param username DOCUMENT ME!
|
||||
* @param digest DOCUMENT ME!
|
||||
* @param nonce DOCUMENT ME!
|
||||
* @param nc DOCUMENT ME!
|
||||
* @param cnonce DOCUMENT ME!
|
||||
* @param qop DOCUMENT ME!
|
||||
* @param realm DOCUMENT ME!
|
||||
* @param md5a2 DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public java.security.Principal authenticate(java.lang.String username, java.lang.String digest,
|
||||
java.lang.String nonce, java.lang.String nc, java.lang.String cnonce, java.lang.String qop,
|
||||
java.lang.String realm, java.lang.String md5a2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported, returns null
|
||||
*
|
||||
* @param x509Certificates DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public Principal authenticate(X509Certificate[] x509Certificates) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getAppContextLocation() {
|
||||
return appContextLocation;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns null (we override authenticate methods)
|
||||
*
|
||||
* @param arg0 DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
protected String getPassword(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns null (we override authenticate methods)
|
||||
*
|
||||
* @param arg0 DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
protected Principal getPrincipal(String arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasRole(Principal principal, String role) {
|
||||
if ((principal == null) || (role == null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(principal instanceof PrincipalAcegiUserToken)) {
|
||||
logger.warn("Expected passed principal to be of type PrincipalAcegiUserToken but was "
|
||||
+ principal.getClass().getName());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken test = (PrincipalAcegiUserToken) principal;
|
||||
|
||||
return test.isUserInRole(role);
|
||||
}
|
||||
|
||||
public void setAppContextLocation(String appContextLocation) {
|
||||
this.appContextLocation = appContextLocation;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the method that Catalina will use to start the container.
|
||||
*
|
||||
* @throws LifecycleException if a problem is detected
|
||||
*/
|
||||
public void start() throws LifecycleException {
|
||||
this.start(true);
|
||||
}
|
||||
|
||||
private void start(boolean startParent) throws LifecycleException {
|
||||
if (startParent) {
|
||||
super.start();
|
||||
}
|
||||
|
||||
if ((appContextLocation == null) || "".equals(appContextLocation)) {
|
||||
throw new LifecycleException("appContextLocation must be defined");
|
||||
}
|
||||
|
||||
if ((key == null) || "".equals(key)) {
|
||||
throw new LifecycleException("key must be defined");
|
||||
}
|
||||
|
||||
File xml = new File(System.getProperty("catalina.base"), appContextLocation);
|
||||
|
||||
if (!xml.exists()) {
|
||||
throw new LifecycleException("appContextLocation does not seem to exist in " + xml.toString());
|
||||
}
|
||||
|
||||
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("file:" + xml.getAbsolutePath());
|
||||
Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
|
||||
|
||||
if (beans.size() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Bean context must contain at least one bean of type AuthenticationManager");
|
||||
}
|
||||
|
||||
String beanName = (String) beans.keySet().iterator().next();
|
||||
authenticationManager = (AuthenticationManager) beans.get(beanName);
|
||||
logger.info("CatalinaAcegiUserRealm Started");
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a method to load the container adapter without delegating to the superclass, which cannot
|
||||
* operate outside the Catalina container.
|
||||
*
|
||||
* @throws LifecycleException if a problem is detected
|
||||
*/
|
||||
protected void startForTest() throws LifecycleException {
|
||||
this.start(false);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Adapter to Catalina web container (Tomcat).
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<!--
|
||||
* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- Data access object which stores authentication information -->
|
||||
<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
||||
<property name="userMap">
|
||||
<value>
|
||||
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
|
||||
dianne=emu,ROLE_TELLER
|
||||
scott=wombat,ROLE_TELLER
|
||||
peter=opal,disabled,ROLE_TELLER
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- The authentication manager is deliberately missing in order to test error detection -->
|
||||
|
||||
</beans>
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
<!--
|
||||
* Copyright 2004 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- Data access object which stores authentication information -->
|
||||
<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
|
||||
<property name="userMap">
|
||||
<value>
|
||||
marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
|
||||
dianne=emu,ROLE_TELLER
|
||||
scott=wombat,ROLE_TELLER
|
||||
peter=opal,disabled,ROLE_TELLER
|
||||
</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Authentication provider that queries our data access object -->
|
||||
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService"><ref bean="inMemoryDaoImpl"/></property>
|
||||
<property name="forcePrincipalAsString"><value>true</value></property>
|
||||
</bean>
|
||||
|
||||
<!-- The authentication manager that iterates through our only authentication provider -->
|
||||
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
|
||||
<property name="providers">
|
||||
<list>
|
||||
<ref bean="daoAuthenticationProvider"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
-275
@@ -1,275 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.catalina;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import org.apache.catalina.LifecycleException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CatalinaAcegiUserRealm}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CatalinaAcegiUserRealmTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final String ADAPTER_KEY = "my_key";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CatalinaAcegiUserRealmTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CatalinaAcegiUserRealmTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CatalinaAcegiUserRealmTests.class);
|
||||
}
|
||||
|
||||
private CatalinaAcegiUserRealm makeAdapter(String fileName)
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
|
||||
URL url = Thread.currentThread().getContextClassLoader().getResource("org/acegisecurity/adapters/" + fileName);
|
||||
|
||||
if (url == null) {
|
||||
throw new Exception("Could not find " + fileName + " - cannot continue");
|
||||
}
|
||||
|
||||
File file = new File(url.getFile());
|
||||
|
||||
System.setProperty("catalina.base", file.getParentFile().getAbsolutePath());
|
||||
System.out.println("catalina.base set to: " + System.getProperty("catalina.base"));
|
||||
adapter.setAppContextLocation(fileName);
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.startForTest();
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean()
|
||||
throws Exception {
|
||||
try {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-invalid.xml");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoAppContextSpecified()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
|
||||
adapter.setKey("KEY");
|
||||
|
||||
try {
|
||||
adapter.startForTest();
|
||||
fail("Should have thrown LifecycleException");
|
||||
} catch (LifecycleException expected) {
|
||||
assertEquals("appContextLocation must be defined", expected.getMessage());
|
||||
}
|
||||
|
||||
adapter.setAppContextLocation("");
|
||||
|
||||
try {
|
||||
adapter.startForTest();
|
||||
fail("Should have thrown LifecycleException");
|
||||
} catch (LifecycleException expected) {
|
||||
assertEquals("appContextLocation must be defined", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoKeySpecified() throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
|
||||
adapter.setAppContextLocation("SOMETHING");
|
||||
|
||||
try {
|
||||
adapter.startForTest();
|
||||
fail("Should have thrown LifecycleException");
|
||||
} catch (LifecycleException expected) {
|
||||
assertEquals("key must be defined", expected.getMessage());
|
||||
}
|
||||
|
||||
adapter.setKey("");
|
||||
|
||||
try {
|
||||
adapter.startForTest();
|
||||
fail("Should have thrown LifecycleException");
|
||||
} catch (LifecycleException expected) {
|
||||
assertEquals("key must be defined", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsWithIncorrectApplicationContextLocation()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
adapter.setAppContextLocation("SOME_INVALID_PATH");
|
||||
adapter.setKey("KEY");
|
||||
|
||||
try {
|
||||
adapter.startForTest();
|
||||
fail("Should have thrown LifecycleException");
|
||||
} catch (LifecycleException expected) {
|
||||
assertTrue(expected.getMessage().startsWith("appContextLocation does not seem to exist in"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterIdentifiesItself() throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertTrue(adapter.getName().lastIndexOf("CatalinaSpringUserRealm") != -1);
|
||||
}
|
||||
|
||||
public void testAdapterStartsUpSuccess() throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testAuthenticateManyParamsReturnsNull() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertEquals(null, adapter.authenticate(null, null, null, null, null, null, null, null));
|
||||
}
|
||||
|
||||
public void testAuthenticateX509ReturnsNull() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertEquals(null, adapter.authenticate(null));
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectPassword()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate("marissa", "kangaroo"));
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectUserName()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate("melissa", "koala"));
|
||||
}
|
||||
|
||||
public void testAuthenticationUsingByteArrayForCredentials()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
byte[] credentials = {'k', 'o', 'a', 'l', 'a'};
|
||||
Principal result = adapter.authenticate("marissa", credentials);
|
||||
|
||||
if (!(result instanceof PrincipalAcegiUserToken)) {
|
||||
fail("Should have returned PrincipalAcegiUserToken");
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash());
|
||||
}
|
||||
|
||||
public void testAuthenticationUsingStringForCredentials()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
Principal result = adapter.authenticate("marissa", "koala");
|
||||
|
||||
if (!(result instanceof PrincipalAcegiUserToken)) {
|
||||
fail("Should have returned PrincipalAcegiUserToken");
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash());
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullPasswordHandledGracefully()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate("marissa", (String) null));
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullUserNameHandledGracefully()
|
||||
throws Exception {
|
||||
CatalinaAcegiUserRealm adapter = makeAdapter("catalinaAdapterTest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate(null, "koala"));
|
||||
}
|
||||
|
||||
public void testGetPasswordReturnsNull() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertEquals(null, adapter.getPassword(null));
|
||||
}
|
||||
|
||||
public void testGetPrincipalReturnsNull() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertEquals(null, adapter.getPrincipal(null));
|
||||
}
|
||||
|
||||
public void testGetters() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
adapter.setKey("KEY");
|
||||
assertEquals("KEY", adapter.getKey());
|
||||
adapter.setAppContextLocation("SOME_LOCATION");
|
||||
assertEquals("SOME_LOCATION", adapter.getAppContextLocation());
|
||||
}
|
||||
|
||||
public void testHasRoleWithANullPrincipalFails() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertTrue(!adapter.hasRole(null, "ROLE_ONE"));
|
||||
}
|
||||
|
||||
public void testHasRoleWithAPrincipalTheAdapterDidNotCreateFails() {
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertTrue(!adapter.hasRole(new Principal() {
|
||||
public String getName() {
|
||||
return "MockPrincipal";
|
||||
}
|
||||
}, "ROLE_ONE"));
|
||||
}
|
||||
|
||||
public void testHasRoleWithPrincipalAcegiUserToken() {
|
||||
PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
|
||||
null);
|
||||
CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm();
|
||||
assertTrue(adapter.hasRole(token, "ROLE_ONE"));
|
||||
assertTrue(adapter.hasRole(token, "ROLE_TWO"));
|
||||
assertTrue(!adapter.hasRole(token, "ROLE_WE_DO_NOT_HAVE"));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
.wtpmodules
|
||||
@@ -1,23 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-jboss</artifactId>
|
||||
<name>Acegi Security System for Spring - JBoss adapter</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jboss</groupId>
|
||||
<artifactId>jbosssx</artifactId>
|
||||
<version>3.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-302
@@ -1,302 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jboss;
|
||||
|
||||
import org.acegisecurity.AccountExpiredException;
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
import org.acegisecurity.CredentialsExpiredException;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.jboss.security.auth.spi.AbstractServerLoginModule;
|
||||
|
||||
import org.springframework.beans.factory.access.BeanFactoryLocator;
|
||||
import org.springframework.beans.factory.access.BeanFactoryReference;
|
||||
import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.FailedLoginException;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to enable JBoss to authenticate via the Acegi Security System for Spring.<p>Returns a {@link
|
||||
* PrincipalAcegiUserToken} to JBoss' authentication system, which is subsequently available from
|
||||
* <code>java:comp/env/security/subject</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @author Sergio Bern�
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JbossAcegiLoginModule extends AbstractServerLoginModule {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
private Principal identity;
|
||||
private String key;
|
||||
private char[] credential;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected Principal getIdentity() {
|
||||
return this.identity;
|
||||
}
|
||||
|
||||
protected Group[] getRoleSets() throws LoginException {
|
||||
SimpleGroup roles = new SimpleGroup("Roles");
|
||||
Group[] roleSets = {roles};
|
||||
|
||||
if (this.identity instanceof Authentication) {
|
||||
Authentication user = (Authentication) this.identity;
|
||||
|
||||
for (int i = 0; i < user.getAuthorities().length; i++) {
|
||||
roles.addMember(new SimplePrincipal(user.getAuthorities()[i].getAuthority()));
|
||||
}
|
||||
}
|
||||
|
||||
return roleSets;
|
||||
}
|
||||
|
||||
protected String[] getUsernameAndPassword() throws LoginException {
|
||||
String[] info = {null, null};
|
||||
|
||||
// prompt for a username and password
|
||||
if (callbackHandler == null) {
|
||||
throw new LoginException("Error: no CallbackHandler available " + "to collect authentication information");
|
||||
}
|
||||
|
||||
NameCallback nc = new NameCallback("User name: ", "guest");
|
||||
PasswordCallback pc = new PasswordCallback("Password: ", false);
|
||||
Callback[] callbacks = {nc, pc};
|
||||
String username = null;
|
||||
String password = null;
|
||||
|
||||
try {
|
||||
callbackHandler.handle(callbacks);
|
||||
username = nc.getName();
|
||||
|
||||
char[] tmpPassword = pc.getPassword();
|
||||
|
||||
if (tmpPassword != null) {
|
||||
credential = new char[tmpPassword.length];
|
||||
System.arraycopy(tmpPassword, 0, credential, 0, tmpPassword.length);
|
||||
pc.clearPassword();
|
||||
password = new String(credential);
|
||||
}
|
||||
} catch (java.io.IOException ioe) {
|
||||
throw new LoginException(ioe.toString());
|
||||
} catch (UnsupportedCallbackException uce) {
|
||||
throw new LoginException("CallbackHandler does not support: " + uce.getCallback());
|
||||
}
|
||||
|
||||
info[0] = username;
|
||||
info[1] = password;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
|
||||
super.initialize(subject, callbackHandler, sharedState, options);
|
||||
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.info("initializing jboss login module");
|
||||
}
|
||||
|
||||
this.key = (String) options.get("key");
|
||||
|
||||
if ((key == null) || "".equals(key)) {
|
||||
throw new IllegalArgumentException("key must be defined");
|
||||
}
|
||||
|
||||
String singletonId = (String) options.get("singletonId");
|
||||
|
||||
String appContextLocation = (String) options.get("appContextLocation");
|
||||
|
||||
if ((((singletonId == null) || "".equals(singletonId)) && (appContextLocation == null))
|
||||
|| "".equals(appContextLocation)) {
|
||||
throw new IllegalArgumentException("appContextLocation must be defined");
|
||||
}
|
||||
|
||||
String beanName = (String) options.get("authenticationManager");
|
||||
|
||||
// Attempt to find the appContextLocation only if no singletonId was defined
|
||||
if ((singletonId == null) || "".equals(singletonId)) {
|
||||
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.info("cannot locate " + appContextLocation);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Cannot locate " + appContextLocation);
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationContext ctx = null;
|
||||
|
||||
if ((singletonId == null) || "".equals(singletonId)) {
|
||||
try {
|
||||
ctx = new ClassPathXmlApplicationContext(appContextLocation);
|
||||
} catch (Exception e) {
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.info("error loading spring context " + appContextLocation + " " + e);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("error loading spring context " + appContextLocation + " " + e);
|
||||
}
|
||||
} else {
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.debug("retrieving singleton instance " + singletonId);
|
||||
}
|
||||
|
||||
BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
|
||||
BeanFactoryReference bf = bfl.useBeanFactory(singletonId);
|
||||
ctx = (ApplicationContext) bf.getFactory();
|
||||
|
||||
if (ctx == null) {
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.info("singleton " + beanName + " does not exists");
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("singleton " + singletonId + " does not exists");
|
||||
}
|
||||
}
|
||||
|
||||
if ((beanName == null) || "".equals(beanName)) {
|
||||
Map beans = null;
|
||||
|
||||
try {
|
||||
beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
|
||||
} catch (Exception e) {
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.info("exception in getBeansOfType " + e);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("spring error in get beans by class");
|
||||
}
|
||||
|
||||
if (beans.size() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Bean context must contain at least one bean of type AuthenticationManager");
|
||||
}
|
||||
|
||||
beanName = (String) beans.keySet().iterator().next();
|
||||
}
|
||||
|
||||
authenticationManager = (AuthenticationManager) ctx.getBean(beanName);
|
||||
|
||||
if (super.log.isInfoEnabled()) {
|
||||
super.log.info("Successfully started JbossSpringLoginModule");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean login() throws LoginException {
|
||||
super.loginOk = false;
|
||||
|
||||
String[] info = getUsernameAndPassword();
|
||||
String username = info[0];
|
||||
String password = info[1];
|
||||
|
||||
if ((username == null) && (password == null)) {
|
||||
identity = null;
|
||||
super.log.trace("Authenticating as unauthenticatedIdentity=" + identity);
|
||||
}
|
||||
|
||||
if (username == null) {
|
||||
username = "";
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
if (super.log.isDebugEnabled()) {
|
||||
super.log.debug("checking identity");
|
||||
}
|
||||
|
||||
if (identity == null) {
|
||||
super.log.debug("creating usernamepassword token");
|
||||
|
||||
Authentication request = new UsernamePasswordAuthenticationToken(username, password);
|
||||
Authentication response = null;
|
||||
|
||||
try {
|
||||
if (super.log.isDebugEnabled()) {
|
||||
super.log.debug("attempting authentication");
|
||||
}
|
||||
|
||||
response = authenticationManager.authenticate(request);
|
||||
|
||||
if (super.log.isDebugEnabled()) {
|
||||
super.log.debug("authentication succeded");
|
||||
}
|
||||
} catch (CredentialsExpiredException cee) {
|
||||
if (super.log.isDebugEnabled()) {
|
||||
super.log.debug("Credential has expired");
|
||||
}
|
||||
|
||||
throw new javax.security.auth.login.CredentialExpiredException(
|
||||
"The credential used to identify the user has expired");
|
||||
} catch (AccountExpiredException cee) {
|
||||
if (super.log.isDebugEnabled()) {
|
||||
super.log.debug("Account has expired, throwing jaas exception");
|
||||
}
|
||||
|
||||
throw new javax.security.auth.login.AccountExpiredException(
|
||||
"The account specified in login has expired");
|
||||
} catch (AuthenticationException failed) {
|
||||
if (super.log.isDebugEnabled()) {
|
||||
super.log.debug("Bad password for username=" + username);
|
||||
}
|
||||
|
||||
throw new FailedLoginException("Password Incorrect/Password Required");
|
||||
}
|
||||
|
||||
super.log.debug("user is logged. redirecting to jaas classes");
|
||||
|
||||
identity = new PrincipalAcegiUserToken(this.key, response.getName(), response.getCredentials().toString(),
|
||||
response.getAuthorities(), response.getPrincipal());
|
||||
}
|
||||
|
||||
if (getUseFirstPass() == true) {
|
||||
// Add the username and password to the shared state map
|
||||
sharedState.put("javax.security.auth.login.name", username);
|
||||
sharedState.put("javax.security.auth.login.password", credential);
|
||||
}
|
||||
|
||||
super.loginOk = true;
|
||||
super.log.trace("User '" + identity + "' authenticated, loginOk=" + loginOk);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jboss;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.acegisecurity.context.HttpSessionContextIntegrationFilter;
|
||||
import org.acegisecurity.context.SecurityContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Populates a {@link SecurityContext} from JBoss' <code>java:comp/env/security/subject</code>.
|
||||
* <p>This filter <b>never</b> preserves the <code>Authentication</code> on the <code>ContextHolder</code> -
|
||||
* it is replaced every request.</p>
|
||||
* <p>See {@link HttpSessionContextIntegrationFilter} for further information.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JbossIntegrationFilter implements Filter {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JbossIntegrationFilter.class);
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Does nothing. We use IoC container lifecycle services instead.
|
||||
*/
|
||||
public void destroy() {}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
Object principal = extractFromContainer(request);
|
||||
|
||||
if ((principal != null) && principal instanceof Authentication) {
|
||||
SecurityContextHolder.getContext().setAuthentication((Authentication) principal);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ContextHolder updated with Authentication from container: '" + principal + "'");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ContextHolder not set with new Authentication as Principal was: '" + principal + "'");
|
||||
}
|
||||
}
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private Object extractFromContainer(ServletRequest request) {
|
||||
Subject subject = null;
|
||||
|
||||
try {
|
||||
Context lc = this.getLookupContext();
|
||||
|
||||
if (lc == null) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Could not obtain a Context to perform lookup");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Object result = lc.lookup("java:comp/env/security/subject");
|
||||
|
||||
if (result instanceof Subject) {
|
||||
subject = (Subject) result;
|
||||
}
|
||||
} catch (NamingException ne) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Lookup on Subject failed " + ne.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ((subject != null) && (subject.getPrincipals() != null)) {
|
||||
Iterator principals = subject.getPrincipals().iterator();
|
||||
|
||||
while (principals.hasNext()) {
|
||||
Principal p = (Principal) principals.next();
|
||||
|
||||
if (p instanceof Authentication) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provided so that unit tests can override.
|
||||
*
|
||||
* @return a <code>Context</code> that can be used for lookup
|
||||
*
|
||||
* @throws NamingException DOCUMENT ME!
|
||||
*/
|
||||
protected Context getLookupContext() throws NamingException {
|
||||
return new InitialContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing. We use IoC container lifecycle services instead.
|
||||
*
|
||||
* @param arg0 ignored
|
||||
*
|
||||
* @throws ServletException ignored
|
||||
*/
|
||||
public void init(FilterConfig arg0) throws ServletException {}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Adapter to JBoss.
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
-358
@@ -1,358 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jboss;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.login.FailedLoginException;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link JbossAcegiLoginModule}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JbossAcegiLoginModuleTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final String ADAPTER_KEY = "my_key";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JbossAcegiLoginModuleTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public JbossAcegiLoginModuleTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(JbossAcegiLoginModuleTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-invalid.xml");
|
||||
|
||||
try {
|
||||
adapter.initialize(null, null, null, props);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoAppContextSpecified()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
|
||||
try {
|
||||
adapter.initialize(null, null, null, props);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("appContextLocation must be defined", expected.getMessage());
|
||||
}
|
||||
|
||||
props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "");
|
||||
|
||||
try {
|
||||
adapter.initialize(null, null, null, props);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("appContextLocation must be defined", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoKeySpecified() throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
try {
|
||||
adapter.initialize(null, null, null, props);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("key must be defined", expected.getMessage());
|
||||
}
|
||||
|
||||
props = new Properties();
|
||||
props.put("key", "");
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
try {
|
||||
adapter.initialize(null, null, null, props);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("key must be defined", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsWithIncorrectApplicationContextLocation()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "INVALID_PATH");
|
||||
|
||||
try {
|
||||
adapter.initialize(null, null, null, props);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue("Cannot locate INVALID_PATH".equals(expected.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterFailsToAuthenticateIfNoCallbackHandlerAvailable()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
|
||||
adapter.initialize(subject, null, null, props);
|
||||
|
||||
try {
|
||||
adapter.login();
|
||||
} catch (LoginException loginException) {
|
||||
assertEquals("Error: no CallbackHandler available to collect authentication information",
|
||||
loginException.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterStartsUpSuccess() throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.initialize(null, null, null, props);
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectPassword()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler("marissa", "kangaroo");
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
|
||||
try {
|
||||
adapter.login();
|
||||
fail("Should have thrown FailedLoginException");
|
||||
} catch (FailedLoginException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectUserName()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler("melissa", "koala");
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
|
||||
try {
|
||||
adapter.login();
|
||||
fail("Should have thrown FailedLoginException");
|
||||
} catch (FailedLoginException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticationSuccess() throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler("marissa", "koala");
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
assertTrue(adapter.login());
|
||||
|
||||
Principal result = adapter.getIdentity();
|
||||
|
||||
if (!(result instanceof PrincipalAcegiUserToken)) {
|
||||
fail("Should have returned PrincipalAcegiUserToken");
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash());
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullPasswordHandledGracefully()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler("marissa", null);
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
|
||||
try {
|
||||
adapter.login();
|
||||
fail("Should have thrown FailedLoginException");
|
||||
} catch (FailedLoginException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullUserNameAndNullPasswordHandledGracefully()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler(null, null);
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
|
||||
try {
|
||||
adapter.login();
|
||||
fail("Should have thrown FailedLoginException");
|
||||
} catch (FailedLoginException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullUserNameHandledGracefully()
|
||||
throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler(null, "kangaroo");
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
|
||||
try {
|
||||
adapter.login();
|
||||
fail("Should have thrown FailedLoginException");
|
||||
} catch (FailedLoginException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetRoleSets() throws Exception {
|
||||
JbossAcegiLoginModule adapter = new JbossAcegiLoginModule();
|
||||
Properties props = new Properties();
|
||||
props.put("key", ADAPTER_KEY);
|
||||
props.put("appContextLocation", "org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
Subject subject = new Subject();
|
||||
CallbackHandler callback = new MockCallbackHandler("marissa", "koala");
|
||||
|
||||
adapter.initialize(subject, callback, null, props);
|
||||
assertTrue(adapter.login());
|
||||
|
||||
Group[] result = adapter.getRoleSets();
|
||||
// Expect Roles group.
|
||||
assertEquals(1, result.length);
|
||||
|
||||
Group roles = result[0];
|
||||
assertTrue(roles.isMember(new SimplePrincipal("ROLE_TELLER")));
|
||||
assertTrue(roles.isMember(new SimplePrincipal("ROLE_SUPERVISOR")));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockCallbackHandler implements CallbackHandler {
|
||||
private String password;
|
||||
private String username;
|
||||
|
||||
public MockCallbackHandler(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
for (int i = 0; i < callbacks.length; i++) {
|
||||
if (callbacks[i] instanceof NameCallback) {
|
||||
((NameCallback) callbacks[i]).setName(username);
|
||||
} else if (callbacks[i] instanceof PasswordCallback) {
|
||||
if (this.password == null) {
|
||||
((PasswordCallback) callbacks[i]).setPassword(null);
|
||||
} else {
|
||||
((PasswordCallback) callbacks[i]).setPassword(password.toCharArray());
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedCallbackException(callbacks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-184
@@ -1,184 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jboss;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.acegisecurity.context.SecurityContextImpl;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link JbossIntegrationFilter}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JbossIntegrationFilterTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JbossIntegrationFilterTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public JbossIntegrationFilterTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
|
||||
ServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
filter.init(filterConfig);
|
||||
filter.doFilter(request, response, filterChain);
|
||||
filter.destroy();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(JbossIntegrationFilterTests.class);
|
||||
}
|
||||
|
||||
private Subject makeIntoSubject(Principal principal) {
|
||||
Set principals = new HashSet();
|
||||
principals.add(principal);
|
||||
|
||||
return new Subject(false, principals, new HashSet(), new HashSet());
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl());
|
||||
}
|
||||
|
||||
public void testCorrectOperation() throws Exception {
|
||||
PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", "someone", "password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}, null);
|
||||
|
||||
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(makeIntoSubject(principal)));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
filter.doFilter(request, null, chain);
|
||||
|
||||
assertEquals(principal, SecurityContextHolder.getContext().getAuthentication());
|
||||
SecurityContextHolder.setContext(new SecurityContextImpl());
|
||||
}
|
||||
|
||||
public void testReturnsNullIfContextReturnsSomethingOtherThanASubject()
|
||||
throws Exception {
|
||||
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext("THIS_IS_NOT_A_SUBJECT"));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
filter.doFilter(request, null, chain);
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
public void testReturnsNullIfInitialContextHasNullPrincipal()
|
||||
throws Exception {
|
||||
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(makeIntoSubject(null)));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
filter.doFilter(request, null, chain);
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
public void testReturnsNullIfInitialContextHasNullSubject()
|
||||
throws Exception {
|
||||
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(null));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
filter.doFilter(request, null, chain);
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
public void testReturnsNullIfInitialContextIsNull()
|
||||
throws Exception {
|
||||
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(null);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
filter.doFilter(request, null, chain);
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
public void testReturnsNullIfPrincipalNotAnAuthenticationImplementation()
|
||||
throws Exception {
|
||||
JbossIntegrationFilter filter = new MockJbossIntegrationFilter(new MockInitialContext(makeIntoSubject(
|
||||
new Principal() {
|
||||
public String getName() {
|
||||
return "MockPrincipal";
|
||||
}
|
||||
})));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
filter.doFilter(request, null, chain);
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
public void testTestingObjectReturnsInitialContext()
|
||||
throws Exception {
|
||||
JbossIntegrationFilter filter = new JbossIntegrationFilter();
|
||||
assertTrue(filter.getLookupContext() instanceof Context);
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockFilterChain implements FilterChain {
|
||||
public void doFilter(ServletRequest arg0, ServletResponse arg1)
|
||||
throws IOException, ServletException {}
|
||||
}
|
||||
}
|
||||
-171
@@ -1,171 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jboss;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NameParser;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
|
||||
/**
|
||||
* Mocks a <code>javax.naming.Context</code> and returns an <code>Object</code> when queried for address
|
||||
* <code>java:comp/env/security/subject</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class MockInitialContext implements Context {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Object object;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public MockInitialContext(Object object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
private MockInitialContext() {
|
||||
super();
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Object addToEnvironment(String propName, Object propVal)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void bind(String name, Object obj) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void close() throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public String composeName(String name, String prefix)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Context createSubcontext(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void destroySubcontext(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Hashtable getEnvironment() throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public NamingEnumeration list(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public NamingEnumeration list(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(String name)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public NamingEnumeration listBindings(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Object lookup(String name) throws NamingException {
|
||||
return this.object;
|
||||
}
|
||||
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Object lookupLink(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void rebind(String name, Object obj) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public Object removeFromEnvironment(String propName)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void rename(String oldName, String newName)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void unbind(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public void unbind(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jboss;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
|
||||
/**
|
||||
* Provides mock of <code>JbossIntegrationFilter</code>, using a lookup <code>Context</code> provided in the
|
||||
* constructor.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class MockJbossIntegrationFilter extends JbossIntegrationFilter {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Context context;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public MockJbossIntegrationFilter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private MockJbossIntegrationFilter() {
|
||||
super();
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected Context getLookupContext() throws NamingException {
|
||||
return this.context;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
.wtpmodules
|
||||
@@ -1,17 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-jetty</artifactId>
|
||||
<name>Acegi Security System for Spring - Jetty adapter</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jetty</groupId>
|
||||
<artifactId>org.mortbay.jetty</artifactId>
|
||||
<version>4.2.22</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-161
@@ -1,161 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jetty;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.mortbay.http.HttpRequest;
|
||||
import org.mortbay.http.UserPrincipal;
|
||||
import org.mortbay.http.UserRealm;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to enable Jetty to authenticate via the Acegi Security System for Spring.<p>Returns a {@link
|
||||
* JettyAcegiUserToken} to Jetty's authentication system, which is subsequently available via
|
||||
* <code>HttpServletRequest.getUserPrincipal()</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public final class JettyAcegiUserRealm implements UserRealm {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(JettyAcegiUserRealm.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
private String key;
|
||||
private String realm;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Construct a <code>SpringUserRealm</code>.
|
||||
*
|
||||
* @param realm the name of the authentication realm (within Jetty)
|
||||
* @param providerKey a password to sign all authentication objects
|
||||
* @param appContextLocation the classpath location of the bean context XML
|
||||
* file
|
||||
*
|
||||
* @throws IllegalArgumentException DOCUMENT ME!
|
||||
*/
|
||||
public JettyAcegiUserRealm(String realm, String providerKey, String appContextLocation) {
|
||||
this.realm = realm;
|
||||
this.key = providerKey;
|
||||
|
||||
if ((realm == null) || "".equals(realm)) {
|
||||
throw new IllegalArgumentException("realm must be specified");
|
||||
}
|
||||
|
||||
if ((key == null) || "".equals(key)) {
|
||||
throw new IllegalArgumentException("key must be specified");
|
||||
}
|
||||
|
||||
if ((appContextLocation == null) || "".equals(appContextLocation)) {
|
||||
throw new IllegalArgumentException("appContextLocation must be specified");
|
||||
}
|
||||
|
||||
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
|
||||
throw new IllegalArgumentException("Cannot locate " + appContextLocation);
|
||||
}
|
||||
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(appContextLocation);
|
||||
Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
|
||||
|
||||
if (beans.size() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Bean context must contain at least one bean of type AuthenticationManager");
|
||||
}
|
||||
|
||||
String beanName = (String) beans.keySet().iterator().next();
|
||||
authenticationManager = (AuthenticationManager) beans.get(beanName);
|
||||
}
|
||||
|
||||
protected JettyAcegiUserRealm() {
|
||||
throw new IllegalArgumentException("Cannot use default constructor");
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public UserPrincipal authenticate(String username, Object password, HttpRequest httpRequest) {
|
||||
if (username == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
Authentication request = new UsernamePasswordAuthenticationToken(username.toString(), password.toString());
|
||||
Authentication response = null;
|
||||
|
||||
try {
|
||||
response = authenticationManager.authenticate(request);
|
||||
} catch (AuthenticationException failed) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return new JettyAcegiUserToken(this.key, response.getPrincipal().toString(),
|
||||
response.getCredentials().toString(), response.getAuthorities());
|
||||
}
|
||||
|
||||
public void disassociate(UserPrincipal userPrincipal) {
|
||||
// No action required
|
||||
}
|
||||
|
||||
public AuthenticationManager getAuthenticationManager() {
|
||||
return authenticationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accesses the realm name.
|
||||
*
|
||||
* @return the name of the realm as defined when <code>SpringUserRealm</code> was created
|
||||
*/
|
||||
public String getName() {
|
||||
return this.realm;
|
||||
}
|
||||
|
||||
public void logout(UserPrincipal arg0) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
public UserPrincipal popRole(UserPrincipal userPrincipal) {
|
||||
// Not supported
|
||||
return userPrincipal;
|
||||
}
|
||||
|
||||
public UserPrincipal pushRole(UserPrincipal userPrincipal, String role) {
|
||||
// Not supported
|
||||
return userPrincipal;
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jetty;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
|
||||
import org.acegisecurity.adapters.AbstractAdapterAuthenticationToken;
|
||||
|
||||
import org.mortbay.http.UserPrincipal;
|
||||
|
||||
|
||||
/**
|
||||
* A Jetty compatible {@link org.acegisecurity.Authentication} object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JettyAcegiUserToken extends AbstractAdapterAuthenticationToken implements UserPrincipal {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String password;
|
||||
private String username;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JettyAcegiUserToken(String key, String username, String password, GrantedAuthority[] authorities) {
|
||||
super(key, authorities);
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
protected JettyAcegiUserToken() {
|
||||
throw new IllegalArgumentException("Cannot use default constructor");
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Object getCredentials() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public Object getPrincipal() {
|
||||
return this.username;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Adapter to Jetty web container.
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
-237
@@ -1,237 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jetty;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.mortbay.http.UserPrincipal;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link JettyAcegiUserRealm}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JettyAcegiUserRealmTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final String ADAPTER_KEY = "my_key";
|
||||
private final String REALM_NAME = "Acegi Powered Realm";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JettyAcegiUserRealmTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public JettyAcegiUserRealmTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(JettyAcegiUserRealmTests.class);
|
||||
}
|
||||
|
||||
private JettyAcegiUserRealm makeAdapter(String fileName)
|
||||
throws Exception {
|
||||
String useFile = "org/acegisecurity/adapters/" + fileName;
|
||||
|
||||
return new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, useFile);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean()
|
||||
throws Exception {
|
||||
try {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-invalid.xml");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Bean context must contain at least one bean of type AuthenticationManager",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoAppContextSpecified()
|
||||
throws Exception {
|
||||
try {
|
||||
new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("appContextLocation must be specified", expected.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, "");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("appContextLocation must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoKeySpecified() throws Exception {
|
||||
try {
|
||||
new JettyAcegiUserRealm(REALM_NAME, null, "SOME_PATH");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("key must be specified", expected.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
new JettyAcegiUserRealm(REALM_NAME, "", "SOME_PATH");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("key must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoRealmNameSpecified()
|
||||
throws Exception {
|
||||
try {
|
||||
new JettyAcegiUserRealm(null, ADAPTER_KEY, "SOME_PATH");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("realm must be specified", expected.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
new JettyAcegiUserRealm(null, ADAPTER_KEY, "SOME_PATH");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("realm must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsWithIncorrectApplicationContextLocation()
|
||||
throws Exception {
|
||||
try {
|
||||
new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, "SOME_INVALID_LOCATION");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(expected.getMessage().startsWith("Cannot locate"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterIdentifiesTheRealmItManages()
|
||||
throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertEquals(REALM_NAME, adapter.getName());
|
||||
}
|
||||
|
||||
public void testAdapterStartsUpSuccess() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectPassword()
|
||||
throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate("marissa", "kangaroo", null));
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectUserName()
|
||||
throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate("melissa", "koala", null));
|
||||
}
|
||||
|
||||
public void testAuthenticationSuccess() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
UserPrincipal result = adapter.authenticate("marissa", "koala", null);
|
||||
|
||||
if (!(result instanceof JettyAcegiUserToken)) {
|
||||
fail("Should have returned JettyAcegiUserToken");
|
||||
}
|
||||
|
||||
JettyAcegiUserToken castResult = (JettyAcegiUserToken) result;
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash());
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullPasswordHandledGracefully()
|
||||
throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate("marissa", null, null));
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullUserNameHandledGracefully()
|
||||
throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertEquals(null, adapter.authenticate(null, "koala", null));
|
||||
}
|
||||
|
||||
public void testDisassociateImplemented() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
adapter.disassociate(new MockUserPrincipal());
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testGetAuthenticationManager() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
assertTrue(adapter.getAuthenticationManager() != null);
|
||||
}
|
||||
|
||||
public void testLogoutImplemented() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
adapter.logout(new MockUserPrincipal());
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testNoArgsConstructor() {
|
||||
try {
|
||||
new JettyAcegiUserRealm();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testPopRoleImplemented() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
MockUserPrincipal user = new MockUserPrincipal();
|
||||
assertEquals(user, adapter.popRole(user));
|
||||
}
|
||||
|
||||
public void testPushRoleImplemented() throws Exception {
|
||||
JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml");
|
||||
MockUserPrincipal user = new MockUserPrincipal();
|
||||
assertEquals(user, adapter.pushRole(user, "SOME_ROLE"));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockUserPrincipal implements UserPrincipal {
|
||||
public String getName() {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public boolean isAuthenticated() {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
|
||||
public boolean isUserInRole(String arg0) {
|
||||
throw new UnsupportedOperationException("mock method not implemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.jetty;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link JettyAcegiUserToken}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JettyAcegiUserTokenTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public JettyAcegiUserTokenTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public JettyAcegiUserTokenTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(JettyAcegiUserTokenTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testGetters() throws Exception {
|
||||
JettyAcegiUserToken token = new JettyAcegiUserToken("my_password", "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
|
||||
assertEquals("Test", token.getPrincipal());
|
||||
assertEquals("Password", token.getCredentials());
|
||||
assertEquals("my_password".hashCode(), token.getKeyHash());
|
||||
assertEquals("Test", token.getName());
|
||||
}
|
||||
|
||||
public void testNoArgsConstructor() {
|
||||
try {
|
||||
new JettyAcegiUserToken();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-parent</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<name>Acegi Security System for Spring - Adapters</name>
|
||||
<packaging>pom</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-mock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<modules>
|
||||
<module>cas</module>
|
||||
<module>catalina</module>
|
||||
<module>jboss</module>
|
||||
<module>jetty</module>
|
||||
<module>resin</module>
|
||||
</modules>
|
||||
</project>
|
||||
@@ -1,5 +0,0 @@
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
.wtpmodules
|
||||
@@ -1,23 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-resin</artifactId>
|
||||
<name>Acegi Security System for Spring - Resin adapter</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.caucho</groupId>
|
||||
<artifactId>resin</artifactId>
|
||||
<version>3.0.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-152
@@ -1,152 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.resin;
|
||||
|
||||
import com.caucho.http.security.AbstractAuthenticator;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Adapter to enable Resin to authenticate via the Acegi Security System for Spring.<p>Returns a {@link
|
||||
* PrincipalAcegiUserToken} to Resin's authentication system, which is subsequently available via
|
||||
* <code>HttpServletRequest.getUserPrincipal()</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ResinAcegiAuthenticator extends AbstractAuthenticator {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ResinAcegiAuthenticator.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
private String appContextLocation;
|
||||
private String key;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public String getAppContextLocation() {
|
||||
return appContextLocation;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void init() throws ServletException {
|
||||
super.init();
|
||||
|
||||
if ((appContextLocation == null) || "".equals(appContextLocation)) {
|
||||
throw new ServletException("appContextLocation must be defined");
|
||||
}
|
||||
|
||||
if ((key == null) || "".equals(key)) {
|
||||
throw new ServletException("key must be defined");
|
||||
}
|
||||
|
||||
if (Thread.currentThread().getContextClassLoader().getResource(appContextLocation) == null) {
|
||||
throw new ServletException("Cannot locate " + appContextLocation);
|
||||
}
|
||||
|
||||
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(appContextLocation);
|
||||
Map beans = ctx.getBeansOfType(AuthenticationManager.class, true, true);
|
||||
|
||||
if (beans.size() == 0) {
|
||||
throw new ServletException("Bean context must contain at least one bean of type AuthenticationManager");
|
||||
}
|
||||
|
||||
String beanName = (String) beans.keySet().iterator().next();
|
||||
authenticationManager = (AuthenticationManager) beans.get(beanName);
|
||||
logger.info("ResinAcegiAuthenticator Started");
|
||||
}
|
||||
|
||||
public boolean isUserInRole(HttpServletRequest request, HttpServletResponse response, ServletContext application,
|
||||
Principal principal, String role) {
|
||||
if (!(principal instanceof PrincipalAcegiUserToken)) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Expected passed principal to be of type PrincipalAcegiUserToken");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken test = (PrincipalAcegiUserToken) principal;
|
||||
|
||||
return test.isUserInRole(role);
|
||||
}
|
||||
|
||||
protected Principal loginImpl(String username, String credentials) {
|
||||
if (username == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (credentials == null) {
|
||||
credentials = "";
|
||||
}
|
||||
|
||||
Authentication request = new UsernamePasswordAuthenticationToken(username, credentials);
|
||||
Authentication response = null;
|
||||
|
||||
try {
|
||||
response = authenticationManager.authenticate(request);
|
||||
} catch (AuthenticationException failed) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PrincipalAcegiUserToken(this.key, response.getPrincipal().toString(),
|
||||
response.getCredentials().toString(), response.getAuthorities(), response.getPrincipal());
|
||||
}
|
||||
|
||||
protected Principal loginImpl(HttpServletRequest request, HttpServletResponse response, ServletContext application,
|
||||
String userName, String password) throws ServletException {
|
||||
return loginImpl(userName, password);
|
||||
}
|
||||
|
||||
public void setAppContextLocation(String appContextLocation) {
|
||||
this.appContextLocation = appContextLocation;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Adapter to Resin web container.
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
-261
@@ -1,261 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.adapters.resin;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
import org.acegisecurity.adapters.PrincipalAcegiUserToken;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link ResinAcegiAuthenticator}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ResinAcegiAuthenticatorTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final String ADAPTER_KEY = "my_key";
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public ResinAcegiAuthenticatorTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ResinAcegiAuthenticatorTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(ResinAcegiAuthenticatorTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-invalid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
|
||||
try {
|
||||
adapter.init();
|
||||
fail("Should have thrown ServletException");
|
||||
} catch (ServletException expected) {
|
||||
assertEquals("Bean context must contain at least one bean of type AuthenticationManager",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoAppContextSpecified()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
|
||||
try {
|
||||
adapter.init();
|
||||
fail("Should have thrown ServletException");
|
||||
} catch (ServletException expected) {
|
||||
assertEquals("appContextLocation must be defined", expected.getMessage());
|
||||
}
|
||||
|
||||
adapter.setAppContextLocation("");
|
||||
|
||||
try {
|
||||
adapter.init();
|
||||
fail("Should have thrown ServletException");
|
||||
} catch (ServletException expected) {
|
||||
assertEquals("appContextLocation must be defined", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsIfNoKeySpecified() throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
|
||||
try {
|
||||
adapter.init();
|
||||
fail("Should have thrown ServletException");
|
||||
} catch (ServletException expected) {
|
||||
assertEquals("key must be defined", expected.getMessage());
|
||||
}
|
||||
|
||||
adapter.setKey("");
|
||||
|
||||
try {
|
||||
adapter.init();
|
||||
fail("Should have thrown ServletException");
|
||||
} catch (ServletException expected) {
|
||||
assertEquals("key must be defined", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterAbortsWithIncorrectApplicationContextLocation()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("FILE_DOES_NOT_EXIST");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
|
||||
try {
|
||||
adapter.init();
|
||||
fail("Should have thrown ServletException");
|
||||
} catch (ServletException expected) {
|
||||
assertTrue(expected.getMessage().startsWith("Cannot locate"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testAdapterStartsUpSuccess() throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectPassword()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertEquals(null, adapter.loginImpl("marissa", "kangaroo"));
|
||||
}
|
||||
|
||||
public void testAuthenticationFailsForIncorrectUserName()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertEquals(null, adapter.loginImpl("melissa", "koala"));
|
||||
}
|
||||
|
||||
public void testAuthenticationSuccess() throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
|
||||
Principal result = adapter.loginImpl("marissa", "koala");
|
||||
|
||||
if (!(result instanceof PrincipalAcegiUserToken)) {
|
||||
fail("Should have returned PrincipalAcegiUserToken");
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash());
|
||||
}
|
||||
|
||||
public void testAuthenticationSuccessUsingAlternateMethod()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
|
||||
Principal result = adapter.loginImpl(null, null, null, "marissa", "koala");
|
||||
|
||||
if (!(result instanceof PrincipalAcegiUserToken)) {
|
||||
fail("Should have returned PrincipalAcegiUserToken");
|
||||
}
|
||||
|
||||
PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result;
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_TELLER", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_SUPERVISOR", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash());
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullPasswordHandledGracefully()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertEquals(null, adapter.loginImpl("marissa", null));
|
||||
}
|
||||
|
||||
public void testAuthenticationWithNullUserNameHandledGracefully()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertEquals(null, adapter.loginImpl(null, "koala"));
|
||||
}
|
||||
|
||||
public void testGetters() throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
assertEquals(ADAPTER_KEY, adapter.getKey());
|
||||
assertEquals("org/acegisecurity/adapters/adaptertest-valid.xml", adapter.getAppContextLocation());
|
||||
}
|
||||
|
||||
public void testHasRoleWithANullPrincipalFails() throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertTrue(!adapter.isUserInRole(null, null, null, null, "ROLE_ONE"));
|
||||
}
|
||||
|
||||
public void testHasRoleWithAPrincipalTheAdapterDidNotCreateFails()
|
||||
throws Exception {
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertTrue(!adapter.isUserInRole(null, null, null,
|
||||
new Principal() {
|
||||
public String getName() {
|
||||
return "MockPrincipal";
|
||||
}
|
||||
}, "ROLE_ONE"));
|
||||
}
|
||||
|
||||
public void testHasRoleWithPrincipalAcegiUserToken()
|
||||
throws Exception {
|
||||
PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", "Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")},
|
||||
null);
|
||||
ResinAcegiAuthenticator adapter = new ResinAcegiAuthenticator();
|
||||
adapter.setAppContextLocation("org/acegisecurity/adapters/adaptertest-valid.xml");
|
||||
adapter.setKey(ADAPTER_KEY);
|
||||
adapter.init();
|
||||
assertTrue(adapter.isUserInRole(null, null, null, token, "ROLE_ONE"));
|
||||
assertTrue(adapter.isUserInRole(null, null, null, token, "ROLE_ONE"));
|
||||
assertTrue(!adapter.isUserInRole(null, null, null, token, "ROLE_WE_DO_NOT_HAVE"));
|
||||
}
|
||||
}
|
||||
+1109
File diff suppressed because it is too large
Load Diff
+9
File diff suppressed because one or more lines are too long
Vendored
+297
@@ -0,0 +1,297 @@
|
||||
/*!
|
||||
* bootstrap-select v1.1.1
|
||||
* https://silviomoreto.github.io/bootstrap-select/
|
||||
*
|
||||
* Copyright 2013 bootstrap-select
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
|
||||
.bootstrap-select.btn-group,
|
||||
.bootstrap-select.btn-group[class*="span"] {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
.form-search .bootstrap-select.btn-group,
|
||||
.form-inline .bootstrap-select.btn-group,
|
||||
.form-horizontal .bootstrap-select.btn-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group.pull-right,
|
||||
.bootstrap-select.btn-group[class*="span"].pull-right,
|
||||
.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.input-append .bootstrap-select.btn-group {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.input-prepend .bootstrap-select.btn-group {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.bootstrap-select:not([class*="span"]) {
|
||||
width: 235px;
|
||||
}
|
||||
|
||||
.bootstrap-select {
|
||||
/*width: 220px\9; IE8 and below*/
|
||||
width: 220px \0/; /*IE9 and below*/
|
||||
}
|
||||
|
||||
.bootstrap-select > .btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error .bootstrap-select .btn {
|
||||
border: 1px solid #b94a48;
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow.open > .btn {
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.bootstrap-select .btn:focus {
|
||||
outline: thin dotted #333333 !important;
|
||||
outline: 5px auto -webkit-focus-ring-color !important;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .btn .filter-option {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
right: 25px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .btn .caret {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 12px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group > .disabled,
|
||||
.bootstrap-select.btn-group .dropdown-menu li.disabled > a {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group > .disabled:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group[class*="span"] .btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group button {
|
||||
font-weight: 400;
|
||||
font-family: "Varela Round", sans-serif;
|
||||
border: 1px solid #34302d;
|
||||
min-width: 100%;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group.open button {
|
||||
background-color: #6db33f;
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group button .filter-option {
|
||||
padding: 6px 0 6px 19px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group.open button .filter-option {
|
||||
padding: 7px 0 5px 20px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group > button.dropdown-toggle {
|
||||
border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group > .dropdown-toggle .item-dropdown--icon {
|
||||
background-color: #34302d;
|
||||
color: #cbcaca;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group.open > .dropdown-toggle .item-dropdown--icon {
|
||||
padding: 10px 10px 10px 9px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group > .dropdown-menu {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu {
|
||||
min-width: 100%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background-color: #34302d;
|
||||
border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li.selected {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu.inner {
|
||||
position: static;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu dt {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .div-contain {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li > a.opt {
|
||||
padding-left: 35px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li > a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu > li > a {
|
||||
color: #f1f1f1;
|
||||
font-size: 14px;
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu > li > a:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
.bootstrap-select.btn-group .spring-icon {
|
||||
vertical-align: top;
|
||||
margin: 2px 0 0 6px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li > dt small {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
margin-top: 2.5px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li a i.check-mark {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text {
|
||||
margin-right: 34px;
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li small {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li:not(.disabled):hover,
|
||||
.bootstrap-select.btn-group .dropdown-menu li:not(.disabled):focus {
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.bootstrap-select.btn-group .dropdown-menu li > dt small {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow .dropdown-toggle:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #CCC;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 9px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow .dropdown-toggle:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid white;
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before {
|
||||
bottom: auto;
|
||||
top: -3px;
|
||||
border-top: 7px solid #ccc;
|
||||
border-bottom: 0;
|
||||
border-top-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after {
|
||||
bottom: auto;
|
||||
top: -3px;
|
||||
border-top: 6px solid #ffffff;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before {
|
||||
right: 12px;
|
||||
left: auto;
|
||||
}
|
||||
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after {
|
||||
right: 13px;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:before,
|
||||
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle:after {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mobile-device {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
opacity: 0;
|
||||
}
|
||||
Vendored
+6167
File diff suppressed because it is too large
Load Diff
Vendored
+9
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Vendored
+659
@@ -0,0 +1,659 @@
|
||||
/*!
|
||||
* bootstrap-select v1.1.1
|
||||
* https://silviomoreto.github.io/bootstrap-select/
|
||||
*
|
||||
* Copyright 2013 bootstrap-select
|
||||
* Licensed under the MIT license
|
||||
*/
|
||||
|
||||
!function($) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var Selectpicker = function(element, options, e) {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
this.$element = $(element);
|
||||
this.$newElement = null;
|
||||
this.$button = null;
|
||||
this.$menu = null;
|
||||
|
||||
//Merge defaults, options and data-attributes to make our options
|
||||
this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options);
|
||||
|
||||
//If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute
|
||||
if (this.options.title == null) {
|
||||
this.options.title = this.$element.attr('title');
|
||||
}
|
||||
|
||||
//Expose public methods
|
||||
this.val = Selectpicker.prototype.val;
|
||||
this.render = Selectpicker.prototype.render;
|
||||
this.refresh = Selectpicker.prototype.refresh;
|
||||
this.setStyle = Selectpicker.prototype.setStyle;
|
||||
this.selectAll = Selectpicker.prototype.selectAll;
|
||||
this.deselectAll = Selectpicker.prototype.deselectAll;
|
||||
this.init();
|
||||
};
|
||||
|
||||
Selectpicker.prototype = {
|
||||
|
||||
constructor: Selectpicker,
|
||||
|
||||
init: function(e) {
|
||||
this.$element.hide();
|
||||
this.multiple = this.$element.prop('multiple');
|
||||
var id = this.$element.attr('id');
|
||||
this.$newElement = this.createView();
|
||||
this.$element.after(this.$newElement);
|
||||
this.$menu = this.$newElement.find('> .dropdown-menu');
|
||||
this.$button = this.$newElement.find('> button');
|
||||
|
||||
if (id !== undefined) {
|
||||
var _this = this;
|
||||
this.$button.attr('data-id', id);
|
||||
$('label[for="' + id + '"]').click(function() {
|
||||
_this.$button.focus();
|
||||
});
|
||||
}
|
||||
|
||||
//If we are multiple, then add the show-tick class by default
|
||||
if (this.multiple) {
|
||||
this.$newElement.addClass('show-tick');
|
||||
}
|
||||
|
||||
this.checkDisabled();
|
||||
this.checkTabIndex();
|
||||
this.clickListener();
|
||||
this.render();
|
||||
this.liHeight();
|
||||
this.setWidth();
|
||||
this.setStyle();
|
||||
if (this.options.container) {
|
||||
this.selectPosition();
|
||||
}
|
||||
this.$menu.data('this', this);
|
||||
this.$newElement.data('this', this);
|
||||
},
|
||||
|
||||
createDropdown: function() {
|
||||
var drop =
|
||||
"<div class='btn-group bootstrap-select'>" +
|
||||
"<button type='button' class='dropdown-toggle' data-toggle='dropdown'>" +
|
||||
"<div class='item-dropdown--icon icon-reorder pull-right'></div>" +
|
||||
"<div class='filter-option pull-left'></div> " +
|
||||
"</button>" +
|
||||
"<div class='dropdown-menu open'>" +
|
||||
"<ul class='dropdown-menu inner' role='menu'>" +
|
||||
"</ul>" +
|
||||
"</div>" +
|
||||
"</div>";
|
||||
|
||||
return $(drop);
|
||||
},
|
||||
|
||||
createView: function() {
|
||||
var $drop = this.createDropdown();
|
||||
var $li = this.createLi();
|
||||
$drop.find('ul').append($li);
|
||||
return $drop;
|
||||
},
|
||||
|
||||
reloadLi: function() {
|
||||
//Remove all children.
|
||||
this.destroyLi();
|
||||
//Re build
|
||||
var $li = this.createLi();
|
||||
this.$newElement.find('ul').append( $li );
|
||||
},
|
||||
|
||||
destroyLi: function() {
|
||||
this.$newElement.find('li').remove();
|
||||
},
|
||||
|
||||
createLi: function() {
|
||||
var _this = this,
|
||||
_liA = [],
|
||||
_liHtml = '';
|
||||
|
||||
this.$element.find('option').each(function(index) {
|
||||
var $this = $(this);
|
||||
|
||||
//Get the class and text for the option
|
||||
var optionClass = $this.attr("class") || '';
|
||||
var inline = $this.attr("style") || '';
|
||||
var text = $this.data('content') ? $this.data('content') : $this.html();
|
||||
var subtext = $this.data('subtext') !== undefined ? '<small class="muted">' + $this.data('subtext') + '</small>' : '';
|
||||
var icon = $this.data('icon') !== undefined ? '<i class="glyphicon '+$this.data('icon')+'"></i> ' : '';
|
||||
if (icon !== '' && ($this.is(':disabled') || $this.parent().is(':disabled'))) {
|
||||
icon = '<span>'+icon+'</span>';
|
||||
}
|
||||
|
||||
if (!$this.data('content')) {
|
||||
//Prepend any icon and append any subtext to the main text.
|
||||
text = icon + '<span class="text">' + text + subtext + '</span>';
|
||||
}
|
||||
|
||||
if (_this.options.hideDisabled && ($this.is(':disabled') || $this.parent().is(':disabled'))) {
|
||||
_liA.push('<a style="min-height: 0; padding: 0"></a>');
|
||||
} else if ($this.parent().is('optgroup') && $this.data('divider') != true) {
|
||||
if ($this.index() == 0) {
|
||||
//Get the opt group label
|
||||
var label = $this.parent().attr('label');
|
||||
var labelSubtext = $this.parent().data('subtext') !== undefined ? '<small class="muted">'+$this.parent().data('subtext')+'</small>' : '';
|
||||
var labelIcon = $this.parent().data('icon') ? '<i class="'+$this.parent().data('icon')+'"></i> ' : '';
|
||||
label = labelIcon + '<span class="text">' + label + labelSubtext + '</span>';
|
||||
|
||||
if ($this[0].index != 0) {
|
||||
_liA.push(
|
||||
'<div class="div-contain"><div class="divider"></div></div>'+
|
||||
'<dt>'+label+'</dt>'+
|
||||
_this.createA(text, "opt " + optionClass, inline )
|
||||
);
|
||||
} else {
|
||||
_liA.push(
|
||||
'<dt>'+label+'</dt>'+
|
||||
_this.createA(text, "opt " + optionClass, inline ));
|
||||
}
|
||||
} else {
|
||||
_liA.push( _this.createA(text, "opt " + optionClass, inline ) );
|
||||
}
|
||||
} else if ($this.data('divider') == true) {
|
||||
_liA.push('<div class="div-contain"><div class="divider"></div></div>');
|
||||
} else if ($(this).data('hidden') == true) {
|
||||
_liA.push('');
|
||||
} else {
|
||||
_liA.push( _this.createA(text, optionClass, inline ) );
|
||||
}
|
||||
});
|
||||
|
||||
$.each(_liA, function(i, item) {
|
||||
_liHtml += "<li rel=" + i + ">" + item + "</li>";
|
||||
});
|
||||
|
||||
//If we are not multiple, and we dont have a selected item, and we dont have a title, select the first element so something is set in the button
|
||||
if (!this.multiple && this.$element.find('option:selected').length==0 && !_this.options.title) {
|
||||
this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
|
||||
}
|
||||
|
||||
return $(_liHtml);
|
||||
},
|
||||
|
||||
createA: function(text, classes, inline) {
|
||||
return '<a tabindex="0" class="'+classes+'" style="'+inline+'">' +
|
||||
text +
|
||||
'<i class="glyphicon glyphicon-ok icon-ok check-mark"></i>' +
|
||||
'</a>';
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var _this = this;
|
||||
|
||||
//Update the LI to match the SELECT
|
||||
this.$element.find('option').each(function(index) {
|
||||
_this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') );
|
||||
_this.setSelected(index, $(this).is(':selected') );
|
||||
});
|
||||
|
||||
var selectedItems = this.$element.find('option:selected').map(function(index,value) {
|
||||
var $this = $(this);
|
||||
var icon = $this.data('icon') && _this.options.showIcon ? '<i class="glyphicon ' + $this.data('icon') + '"></i> ' : '';
|
||||
var subtext;
|
||||
if (_this.options.showSubtext && $this.attr('data-subtext') && !_this.multiple) {
|
||||
subtext = ' <small class="muted">'+$this.data('subtext') +'</small>';
|
||||
} else {
|
||||
subtext = '';
|
||||
}
|
||||
if ($this.data('content') && _this.options.showContent) {
|
||||
return $this.data('content');
|
||||
} else if ($this.attr('title') != undefined) {
|
||||
return $this.attr('title');
|
||||
} else {
|
||||
return icon + $this.html() + subtext;
|
||||
}
|
||||
}).toArray();
|
||||
|
||||
//Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled
|
||||
//Convert all the values into a comma delimited string
|
||||
var title = !this.multiple ? selectedItems[0] : selectedItems.join(", ");
|
||||
|
||||
//If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
|
||||
if (_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) {
|
||||
var max = _this.options.selectedTextFormat.split(">");
|
||||
var notDisabled = this.options.hideDisabled ? ':not([disabled])' : '';
|
||||
if ( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) {
|
||||
title = _this.options.countSelectedText.replace('{0}', selectedItems.length).replace('{1}', this.$element.find('option:not([data-divider="true"]):not([data-hidden="true"])'+notDisabled).length);
|
||||
}
|
||||
}
|
||||
|
||||
//If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
|
||||
if (!title) {
|
||||
title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText;
|
||||
}
|
||||
|
||||
_this.$newElement.find('.filter-option').html(title);
|
||||
},
|
||||
|
||||
setStyle: function(style, status) {
|
||||
if (this.$element.attr('class')) {
|
||||
this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device/gi, ''));
|
||||
}
|
||||
|
||||
var buttonClass = style ? style : this.options.style;
|
||||
|
||||
if (status == 'add') {
|
||||
this.$button.addClass(buttonClass);
|
||||
} else {
|
||||
this.$button.removeClass(this.options.style);
|
||||
this.$button.addClass(buttonClass);
|
||||
}
|
||||
},
|
||||
|
||||
liHeight: function() {
|
||||
var selectClone = this.$newElement.clone();
|
||||
selectClone.appendTo('body');
|
||||
var liHeight = selectClone.addClass('open').find('.dropdown-menu li > a').outerHeight();
|
||||
selectClone.remove();
|
||||
this.$newElement.data('liHeight', liHeight);
|
||||
},
|
||||
|
||||
setSize: function() {
|
||||
var _this = this,
|
||||
menu = this.$menu,
|
||||
menuInner = menu.find('.inner'),
|
||||
menuA = menuInner.find('li > a'),
|
||||
selectHeight = this.$newElement.outerHeight(),
|
||||
liHeight = this.$newElement.data('liHeight'),
|
||||
divHeight = menu.find('li .divider').outerHeight(true),
|
||||
menuPadding = parseInt(menu.css('padding-top')) +
|
||||
parseInt(menu.css('padding-bottom')) +
|
||||
parseInt(menu.css('border-top-width')) +
|
||||
parseInt(menu.css('border-bottom-width')),
|
||||
notDisabled = this.options.hideDisabled ? ':not(.disabled)' : '',
|
||||
$window = $(window),
|
||||
menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2,
|
||||
menuHeight,
|
||||
selectOffsetTop,
|
||||
selectOffsetBot,
|
||||
posVert = function() {
|
||||
selectOffsetTop = _this.$newElement.offset().top - $window.scrollTop();
|
||||
selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;
|
||||
};
|
||||
posVert();
|
||||
|
||||
if (this.options.size == 'auto') {
|
||||
var getSize = function() {
|
||||
var minHeight;
|
||||
posVert();
|
||||
menuHeight = selectOffsetBot - menuExtras;
|
||||
_this.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && (menuHeight - menuExtras) < menu.height() && _this.options.dropupAuto);
|
||||
if (_this.$newElement.hasClass('dropup')) {
|
||||
menuHeight = selectOffsetTop - menuExtras;
|
||||
}
|
||||
if ((menu.find('li').length + menu.find('dt').length) > 3) {
|
||||
minHeight = liHeight*3 + menuExtras - 2;
|
||||
} else {
|
||||
minHeight = 0;
|
||||
}
|
||||
menu.css({'max-height' : menuHeight + 'px', 'overflow' : 'hidden', 'min-height' : minHeight + 'px'});
|
||||
menuInner.css({'max-height' : (menuHeight - menuPadding) + 'px', 'overflow-y' : 'auto', 'min-height' : (minHeight - menuPadding) + 'px'});
|
||||
}
|
||||
getSize();
|
||||
$(window).resize(getSize);
|
||||
$(window).scroll(getSize);
|
||||
} else if (this.options.size && this.options.size != 'auto' && menu.find('li'+notDisabled).length > this.options.size) {
|
||||
var optIndex = menu.find("li"+notDisabled+" > *").filter(':not(.div-contain)').slice(0,this.options.size).last().parent().index();
|
||||
var divLength = menu.find("li").slice(0,optIndex + 1).find('.div-contain').length;
|
||||
menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding;
|
||||
this.$newElement.toggleClass('dropup', (selectOffsetTop > selectOffsetBot) && menuHeight < menu.height() && this.options.dropupAuto);
|
||||
menu.css({'max-height' : menuHeight + 'px', 'overflow' : 'hidden'});
|
||||
menuInner.css({'max-height' : (menuHeight - menuPadding) + 'px', 'overflow-y' : 'auto'});
|
||||
}
|
||||
},
|
||||
|
||||
setWidth: function() {
|
||||
//Set width of select
|
||||
if (this.options.width == 'auto') {
|
||||
this.$menu.css('min-width','0');
|
||||
|
||||
// Get correct width if element hidden
|
||||
var selectClone = this.$newElement.clone().appendTo('body');
|
||||
var ulWidth = selectClone.find('> .dropdown-menu').css('width');
|
||||
selectClone.remove();
|
||||
|
||||
this.$newElement.css('width',ulWidth);
|
||||
} else if (this.options.width) {
|
||||
this.$newElement.css('width',this.options.width);
|
||||
}
|
||||
},
|
||||
|
||||
selectPosition: function() {
|
||||
var _this = this,
|
||||
drop = "<div />",
|
||||
$drop = $(drop),
|
||||
pos,
|
||||
actualHeight,
|
||||
getPlacement = function($element) {
|
||||
$drop.addClass($element.attr('class')).toggleClass('dropup', $element.hasClass('dropup'));
|
||||
pos = $element.offset();
|
||||
actualHeight = $element.hasClass('dropup') ? 0 : $element[0].offsetHeight;
|
||||
$drop.css({'top' : pos.top + actualHeight, 'left' : pos.left, 'width' : $element[0].offsetWidth, 'position' : 'absolute'});
|
||||
};
|
||||
this.$newElement.on('click', function(e) {
|
||||
getPlacement($(this));
|
||||
$drop.appendTo(_this.options.container);
|
||||
$drop.toggleClass('open', !$(this).hasClass('open'));
|
||||
$drop.append(_this.$menu);
|
||||
});
|
||||
$(window).resize(function() {
|
||||
getPlacement(_this.$newElement);
|
||||
});
|
||||
$(window).on('scroll', function(e) {
|
||||
getPlacement(_this.$newElement);
|
||||
});
|
||||
$('html').on('click', function(e) {
|
||||
if ($(e.target).closest(_this.$newElement).length < 1) {
|
||||
$drop.removeClass('open');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
mobile: function() {
|
||||
this.$element.addClass('mobile-device').appendTo(this.$newElement);
|
||||
if (this.options.container) this.$menu.hide();
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
this.reloadLi();
|
||||
this.render();
|
||||
this.setWidth();
|
||||
this.setStyle();
|
||||
this.checkDisabled();
|
||||
},
|
||||
|
||||
setSelected: function(index, selected) {
|
||||
this.$menu.find('li').eq(index).toggleClass('selected', selected);
|
||||
},
|
||||
|
||||
setDisabled: function(index, disabled) {
|
||||
if (disabled) {
|
||||
this.$menu.find('li').eq(index).addClass('disabled').find('a').attr('href','#').attr('tabindex',-1);
|
||||
} else {
|
||||
this.$menu.find('li').eq(index).removeClass('disabled').find('a').removeAttr('href').attr('tabindex',0);
|
||||
}
|
||||
},
|
||||
|
||||
isDisabled: function() {
|
||||
return this.$element.is(':disabled');
|
||||
},
|
||||
|
||||
checkDisabled: function() {
|
||||
var _this = this;
|
||||
if (this.isDisabled()) {
|
||||
this.$button.addClass('disabled');
|
||||
this.$button.attr('tabindex','-1');
|
||||
} else if (this.$button.hasClass('disabled')) {
|
||||
this.$button.removeClass('disabled');
|
||||
this.$button.removeAttr('tabindex');
|
||||
}
|
||||
this.$button.click(function() {
|
||||
return !_this.isDisabled();
|
||||
});
|
||||
},
|
||||
|
||||
checkTabIndex: function() {
|
||||
if (this.$element.is('[tabindex]')) {
|
||||
var tabindex = this.$element.attr("tabindex");
|
||||
this.$button.attr('tabindex', tabindex);
|
||||
}
|
||||
},
|
||||
|
||||
clickListener: function() {
|
||||
var _this = this;
|
||||
|
||||
$('body').on('touchstart.dropdown', '.dropdown-menu', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
this.$newElement.on('click', function() {
|
||||
_this.setSize();
|
||||
});
|
||||
|
||||
this.$menu.on('click', 'li a', function(e) {
|
||||
var clickedIndex = $(this).parent().index(),
|
||||
$this = $(this).parent(),
|
||||
prevValue = _this.$element.val();
|
||||
|
||||
//Dont close on multi choice menu
|
||||
if (_this.multiple) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
//Dont run if we have been disabled
|
||||
if (!_this.isDisabled() && !$(this).parent().hasClass('disabled')) {
|
||||
var $options = _this.$element.find('option');
|
||||
var $option = $options.eq(clickedIndex);
|
||||
|
||||
//Deselect all others if not multi select box
|
||||
if (!_this.multiple) {
|
||||
$options.prop('selected', false);
|
||||
$option.prop('selected', true);
|
||||
}
|
||||
//Else toggle the one we have chosen if we are multi select.
|
||||
else {
|
||||
var state = $option.prop('selected');
|
||||
|
||||
$option.prop('selected', !state);
|
||||
}
|
||||
|
||||
_this.$button.focus();
|
||||
|
||||
// Trigger select 'change'
|
||||
if (prevValue != _this.$element.val()) {
|
||||
_this.$element.change();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.$menu.on('click', 'li.disabled a, li dt, li .div-contain', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
_this.$button.focus();
|
||||
});
|
||||
|
||||
this.$element.change(function() {
|
||||
_this.render()
|
||||
});
|
||||
},
|
||||
|
||||
val: function(value) {
|
||||
|
||||
if (value != undefined) {
|
||||
this.$element.val( value );
|
||||
|
||||
this.$element.change();
|
||||
return this.$element;
|
||||
} else {
|
||||
return this.$element.val();
|
||||
}
|
||||
},
|
||||
|
||||
selectAll: function() {
|
||||
this.$element.find('option').prop('selected', true).attr('selected', 'selected');
|
||||
this.render();
|
||||
},
|
||||
|
||||
deselectAll: function() {
|
||||
this.$element.find('option').prop('selected', false).removeAttr('selected');
|
||||
this.render();
|
||||
},
|
||||
|
||||
keydown: function(e) {
|
||||
var $this,
|
||||
$items,
|
||||
$parent,
|
||||
index,
|
||||
next,
|
||||
first,
|
||||
last,
|
||||
prev,
|
||||
nextPrev,
|
||||
that;
|
||||
|
||||
$this = $(this);
|
||||
|
||||
$parent = $this.parent();
|
||||
|
||||
that = $parent.data('this');
|
||||
|
||||
if (that.options.container) $parent = that.$menu;
|
||||
|
||||
$items = $('[role=menu] li:not(.divider):visible a', $parent);
|
||||
|
||||
if (!$items.length) return;
|
||||
|
||||
if (/(38|40)/.test(e.keyCode)) {
|
||||
|
||||
index = $items.index($items.filter(':focus'));
|
||||
first = $items.parent(':not(.disabled)').first().index();
|
||||
last = $items.parent(':not(.disabled)').last().index();
|
||||
next = $items.eq(index).parent().nextAll(':not(.disabled)').eq(0).index();
|
||||
prev = $items.eq(index).parent().prevAll(':not(.disabled)').eq(0).index();
|
||||
nextPrev = $items.eq(next).parent().prevAll(':not(.disabled)').eq(0).index();
|
||||
|
||||
if (e.keyCode == 38) {
|
||||
if (index != nextPrev && index > prev) index = prev;
|
||||
if (index < first) index = first;
|
||||
}
|
||||
|
||||
if (e.keyCode == 40) {
|
||||
if (index != nextPrev && index < next) index = next;
|
||||
if (index > last) index = last;
|
||||
if (index == -1) index = 0;
|
||||
}
|
||||
|
||||
$items.eq(index).focus();
|
||||
} else {
|
||||
var keyCodeMap = {
|
||||
48:"0", 49:"1", 50:"2", 51:"3", 52:"4", 53:"5", 54:"6", 55:"7", 56:"8", 57:"9", 59:";",
|
||||
65:"a", 66:"b", 67:"c", 68:"d", 69:"e", 70:"f", 71:"g", 72:"h", 73:"i", 74:"j", 75:"k", 76:"l",
|
||||
77:"m", 78:"n", 79:"o", 80:"p", 81:"q", 82:"r", 83:"s", 84:"t", 85:"u", 86:"v", 87:"w", 88:"x", 89:"y", 90:"z",
|
||||
96:"0", 97:"1", 98:"2", 99:"3", 100:"4", 101:"5", 102:"6", 103:"7", 104:"8", 105:"9"
|
||||
}
|
||||
|
||||
var keyIndex = [];
|
||||
|
||||
$items.each(function() {
|
||||
if ($(this).parent().is(':not(.disabled)')) {
|
||||
if ($.trim($(this).text().toLowerCase()).substring(0,1) == keyCodeMap[e.keyCode]) {
|
||||
keyIndex.push($(this).parent().index());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var count = $(document).data('keycount');
|
||||
count++;
|
||||
$(document).data('keycount',count);
|
||||
|
||||
var prevKey = $.trim($(':focus').text().toLowerCase()).substring(0,1);
|
||||
|
||||
if (prevKey != keyCodeMap[e.keyCode]) {
|
||||
count = 1;
|
||||
$(document).data('keycount',count);
|
||||
} else if (count >= keyIndex.length) {
|
||||
$(document).data('keycount',0);
|
||||
}
|
||||
|
||||
$items.eq(keyIndex[count - 1]).focus();
|
||||
}
|
||||
|
||||
// select focused option if "Enter" or "Spacebar" are pressed
|
||||
if (/(13|32)/.test(e.keyCode)) {
|
||||
$(':focus').click();
|
||||
if (!that.multiple) {
|
||||
$parent.parent().toggleClass('open', !(e.keyCode == 32));
|
||||
} else {
|
||||
e.preventDefault();
|
||||
};
|
||||
$(document).data('keycount',0);
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.$newElement.hide();
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this.$newElement.show();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.$newElement.remove();
|
||||
this.$element.remove();
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.selectpicker = function(option, event) {
|
||||
//get the args of the outer function..
|
||||
var args = arguments;
|
||||
var value;
|
||||
var chain = this.each(function() {
|
||||
if ($(this).is('select')) {
|
||||
var $this = $(this),
|
||||
data = $this.data('selectpicker'),
|
||||
options = typeof option == 'object' && option;
|
||||
|
||||
if (!data) {
|
||||
$this.data('selectpicker', (data = new Selectpicker(this, options, event)));
|
||||
} else if (options) {
|
||||
for(var i in options) {
|
||||
data.options[i] = options[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof option == 'string') {
|
||||
//Copy the value of option, as once we shift the arguments
|
||||
//it also shifts the value of option.
|
||||
var property = option;
|
||||
if (data[property] instanceof Function) {
|
||||
[].shift.apply(args);
|
||||
value = data[property].apply(data, args);
|
||||
} else {
|
||||
value = data.options[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (value != undefined) {
|
||||
return value;
|
||||
} else {
|
||||
return chain;
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.selectpicker.defaults = {
|
||||
style: null,
|
||||
size: 'auto',
|
||||
title: null,
|
||||
selectedTextFormat : 'values',
|
||||
noneSelectedText : 'Nothing selected',
|
||||
countSelectedText: '{0} of {1} selected',
|
||||
width: null,
|
||||
container: false,
|
||||
hideDisabled: false,
|
||||
showSubtext: false,
|
||||
showIcon: true,
|
||||
showContent: true,
|
||||
dropupAuto: true
|
||||
}
|
||||
|
||||
$(document)
|
||||
.data('keycount', 0)
|
||||
.on('keydown', '[data-toggle=dropdown], [role=menu]' , Selectpicker.prototype.keydown)
|
||||
|
||||
}(window.jQuery);
|
||||
Vendored
+2280
File diff suppressed because it is too large
Load Diff
Vendored
+6
File diff suppressed because one or more lines are too long
@@ -1,5 +0,0 @@
|
||||
target
|
||||
.settings
|
||||
.classpath
|
||||
.project
|
||||
.wtpmodules
|
||||
@@ -1,47 +0,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>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-parent</artifactId>
|
||||
<version>1.0.7</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-tiger</artifactId>
|
||||
<name>Acegi Security System for Spring - Java 5 (Tiger)</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<configuration>
|
||||
<targetJdk>1.5</targetJdk>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</project>
|
||||
@@ -1,56 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Java 5 annotation for describing service layer security attributes.
|
||||
*
|
||||
* <p>The <code>Secured</code> annotation is used to define a list of security
|
||||
* configuration attributes for business methods. This annotation can be used
|
||||
* as a Java 5 alternative to XML configuration.
|
||||
* <p>For example:
|
||||
* <pre>
|
||||
* @Secured ({"ROLE_USER"})
|
||||
* public void create(Contact contact);
|
||||
*
|
||||
* @Secured ({"ROLE_USER", "ROLE_ADMIN"})
|
||||
* public void update(Contact contact);
|
||||
*
|
||||
* @Secured ({"ROLE_ADMIN"})
|
||||
* public void delete(Contact contact);
|
||||
* </pre>
|
||||
* @author Mark St.Godard
|
||||
* @version $Id$
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface Secured {
|
||||
/**
|
||||
* Returns the list of security configuration attributes.
|
||||
* (i.e. ROLE_USER, ROLE_ADMIN etc.)
|
||||
* @return String[] The secure method attributes
|
||||
*/
|
||||
public String[] value();
|
||||
}
|
||||
-141
@@ -1,141 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation;
|
||||
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
import org.springframework.metadata.Attributes;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Java 5 Annotation <code>Attributes</code> metadata implementation used for secure method interception.<p>This
|
||||
* <code>Attributes</code> implementation will return security configuration for classes described using the
|
||||
* <code>Secured</code> Java 5 annotation.</p>
|
||||
* <p>The <code>SecurityAnnotationAttributes</code> implementation can be used to configure a
|
||||
* <code>MethodDefinitionAttributes</code> and <code>MethodSecurityInterceptor</code> bean definition (see below).</p>
|
||||
* <p>For example:<pre><bean id="attributes"
|
||||
* class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/><bean id="objectDefinitionSource"
|
||||
* class="org.acegisecurity.intercept.method.MethodDefinitionAttributes"> <property name="attributes">
|
||||
* <ref local="attributes"/> </property></bean><bean id="securityInterceptor"
|
||||
* class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"> . . .
|
||||
* <property name="objectDefinitionSource"> <ref local="objectDefinitionSource"/> </property>
|
||||
* </bean></pre></p>
|
||||
* <p>These security annotations are similiar to the Commons Attributes approach, however they are using Java 5
|
||||
* language-level metadata support.</p>
|
||||
* <p>This class should be used with Spring 2.0 or above, as it relies upon utility classes in Spring 2.0 for
|
||||
* correct introspection of annotations on bridge methods.</p>
|
||||
*
|
||||
* @author Mark St.Godard
|
||||
* @version $Id$
|
||||
*
|
||||
* @see org.acegisecurity.annotation.Secured
|
||||
*/
|
||||
public class SecurityAnnotationAttributes implements Attributes {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Get the <code>Secured</code> attributes for a given target class.
|
||||
*
|
||||
* @param target The target method
|
||||
*
|
||||
* @return Collection of <code>SecurityConfig</code>
|
||||
*
|
||||
* @see Attributes#getAttributes
|
||||
*/
|
||||
public Collection getAttributes(Class target) {
|
||||
Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
|
||||
|
||||
for (Annotation annotation : target.getAnnotations()) {
|
||||
// check for Secured annotations
|
||||
if (annotation instanceof Secured) {
|
||||
Secured attr = (Secured) annotation;
|
||||
|
||||
for (String auth : attr.value()) {
|
||||
attributes.add(new SecurityConfig(auth));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public Collection getAttributes(Class clazz, Class filter) {
|
||||
throw new UnsupportedOperationException("Unsupported operation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <code>Secured</code> attributes for a given target method.
|
||||
*
|
||||
* @param method The target method
|
||||
*
|
||||
* @return Collection of <code>SecurityConfig</code>
|
||||
*
|
||||
* @see Attributes#getAttributes
|
||||
*/
|
||||
public Collection getAttributes(Method method) {
|
||||
Set<SecurityConfig> attributes = new HashSet<SecurityConfig>();
|
||||
|
||||
Annotation[] annotations = null;
|
||||
|
||||
// Use AnnotationUtils if in classpath (ie Spring 1.2.9+ deployment)
|
||||
try {
|
||||
Class clazz = ClassUtils.forName("org.springframework.core.annotation.AnnotationUtils");
|
||||
Method m = clazz.getMethod("getAnnotations", new Class[] {Method.class});
|
||||
annotations = (Annotation[]) m.invoke(null, new Object[] {method});
|
||||
} catch (Exception ex) {
|
||||
// Fallback to manual retrieval if no AnnotationUtils available
|
||||
annotations = method.getAnnotations();
|
||||
}
|
||||
|
||||
for (Annotation annotation : annotations) {
|
||||
// check for Secured annotations
|
||||
if (annotation instanceof Secured) {
|
||||
Secured attr = (Secured) annotation;
|
||||
|
||||
for (String auth : attr.value()) {
|
||||
attributes.add(new SecurityConfig(auth));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public Collection getAttributes(Method method, Class clazz) {
|
||||
throw new UnsupportedOperationException("Unsupported operation");
|
||||
}
|
||||
|
||||
public Collection getAttributes(Field field) {
|
||||
throw new UnsupportedOperationException("Unsupported operation");
|
||||
}
|
||||
|
||||
public Collection getAttributes(Field field, Class clazz) {
|
||||
throw new UnsupportedOperationException("Unsupported operation");
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author $author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
@Secured({"ROLE_USER"})
|
||||
public interface BusinessService {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@Secured({"ROLE_ADMIN"})
|
||||
public void someAdminMethod();
|
||||
|
||||
@Secured({"ROLE_USER", "ROLE_ADMIN"})
|
||||
public void someUserAndAdminMethod();
|
||||
|
||||
@Secured({"ROLE_USER"})
|
||||
public void someUserMethod1();
|
||||
|
||||
@Secured({"ROLE_USER"})
|
||||
public void someUserMethod2();
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.acegisecurity.annotation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Joe Scalise
|
||||
*/
|
||||
public class BusinessServiceImpl<E extends Entity> implements BusinessService {
|
||||
|
||||
@Secured({"ROLE_USER"})
|
||||
public void someUserMethod1() {
|
||||
}
|
||||
|
||||
@Secured({"ROLE_USER"})
|
||||
public void someUserMethod2() {
|
||||
}
|
||||
|
||||
@Secured({"ROLE_USER", "ROLE_ADMIN"})
|
||||
public void someUserAndAdminMethod() {
|
||||
}
|
||||
|
||||
@Secured({"ROLE_ADMIN"})
|
||||
public void someAdminMethod() {
|
||||
}
|
||||
|
||||
public E someUserMethod3(final E entity) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package org.acegisecurity.annotation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Joe Scalise
|
||||
*/
|
||||
public class Department extends Entity {
|
||||
//~ Instance fields ========================================================
|
||||
|
||||
private boolean active = true;
|
||||
|
||||
//~ Constructors ===========================================================
|
||||
|
||||
public Department(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
//~ Methods ================================================================
|
||||
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
void deactive() {
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.acegisecurity.annotation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Joe Scalise
|
||||
*/
|
||||
public interface DepartmentService extends BusinessService {
|
||||
|
||||
@Secured({"ROLE_USER"})
|
||||
Department someUserMethod3(Department dept);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package org.acegisecurity.annotation;
|
||||
|
||||
/**
|
||||
* @author Joe Scalise
|
||||
*/
|
||||
public class DepartmentServiceImpl extends BusinessServiceImpl <Department> implements DepartmentService {
|
||||
|
||||
@Secured({"ROLE_ADMIN"})
|
||||
public Department someUserMethod3(final Department dept) {
|
||||
return super.someUserMethod3(dept);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.acegisecurity.annotation;
|
||||
|
||||
/**
|
||||
* Class to act as a superclass for annotations testing.
|
||||
*
|
||||
* @author Ben Alex
|
||||
*
|
||||
*/
|
||||
public class Entity {
|
||||
public Entity(String someParameter) {}
|
||||
}
|
||||
-150
@@ -1,150 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation;
|
||||
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
import org.acegisecurity.annotation.test.Entity;
|
||||
import org.acegisecurity.annotation.test.OrganisationService;
|
||||
import org.acegisecurity.annotation.test.PersonService;
|
||||
import org.acegisecurity.annotation.test.PersonServiceImpl;
|
||||
import org.acegisecurity.annotation.test.Service;
|
||||
import org.acegisecurity.annotation.test.ServiceImpl;
|
||||
import org.acegisecurity.intercept.method.MethodDefinitionMap;
|
||||
import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
|
||||
/**
|
||||
* Extra tests to demonstrate generics behaviour with <code>MethodDefinitionMap</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class MethodDefinitionSourceEditorTigerTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public MethodDefinitionSourceEditorTigerTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MethodDefinitionSourceEditorTigerTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(MethodDefinitionSourceEditorTigerTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testConcreteClassInvocationsAlsoReturnDefinitionsAgainstInterface()
|
||||
throws Exception {
|
||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
||||
editor.setAsText(
|
||||
"org.acegisecurity.annotation.test.Service.makeLower*=ROLE_FROM_INTERFACE\r\norg.acegisecurity.annotation.test.Service.makeUpper*=ROLE_FROM_INTERFACE\r\norg.acegisecurity.annotation.test.ServiceImpl.makeUpper*=ROLE_FROM_IMPLEMENTATION");
|
||||
|
||||
MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
|
||||
assertEquals(3, map.getMethodMapSize());
|
||||
|
||||
ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(Service.class,
|
||||
"makeLowerCase", new Class[] {Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition();
|
||||
expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE"));
|
||||
assertEquals(expectedMakeLower, returnedMakeLower);
|
||||
|
||||
ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(ServiceImpl.class,
|
||||
"makeUpperCase", new Class[] {Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition();
|
||||
expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_IMPLEMENTATION"));
|
||||
expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE"));
|
||||
assertEquals(expectedMakeUpper, returnedMakeUpper);
|
||||
}
|
||||
|
||||
public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride()
|
||||
throws Exception {
|
||||
MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
|
||||
editor.setAsText(
|
||||
"org.acegisecurity.annotation.test.Service.makeLower*=ROLE_FROM_INTERFACE\r\norg.acegisecurity.annotation.test.Service.makeUpper*=ROLE_FROM_INTERFACE\r\norg.acegisecurity.annotation.test.ServiceImpl.makeUpper*=ROLE_FROM_IMPLEMENTATION");
|
||||
|
||||
MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
|
||||
assertEquals(3, map.getMethodMapSize());
|
||||
|
||||
ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(PersonService.class,
|
||||
"makeLowerCase", new Class[] {Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition();
|
||||
expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE"));
|
||||
assertEquals(expectedMakeLower, returnedMakeLower);
|
||||
|
||||
ConfigAttributeDefinition returnedMakeLower2 = map.getAttributes(new MockMethodInvocation(
|
||||
OrganisationService.class, "makeLowerCase", new Class[] {Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeLower2 = new ConfigAttributeDefinition();
|
||||
expectedMakeLower2.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE"));
|
||||
assertEquals(expectedMakeLower2, returnedMakeLower2);
|
||||
|
||||
ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(
|
||||
PersonServiceImpl.class, "makeUpperCase", new Class[] {Entity.class}));
|
||||
ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition();
|
||||
expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_IMPLEMENTATION"));
|
||||
expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_FROM_INTERFACE"));
|
||||
assertEquals(expectedMakeUpper, returnedMakeUpper);
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockMethodInvocation implements MethodInvocation {
|
||||
Method method;
|
||||
|
||||
private MockMethodInvocation() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MockMethodInvocation(Class clazz, String methodName, Class[] parameterTypes)
|
||||
throws NoSuchMethodException {
|
||||
System.out.println(clazz + " " + methodName + " " + parameterTypes[0]);
|
||||
method = clazz.getMethod(methodName, parameterTypes);
|
||||
}
|
||||
|
||||
public Object[] getArguments() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public AccessibleObject getStaticPart() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getThis() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object proceed() throws Throwable {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
-200
@@ -1,200 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.metadata.Attributes;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link org.acegisecurity.annotation.SecurityAnnotationAttributes}
|
||||
*
|
||||
* @author Mark St.Godard
|
||||
* @author Joe Scalise
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecurityAnnotationAttributesTests extends TestCase {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private Attributes attributes;
|
||||
private Log logger = LogFactory.getLog(SecurityAnnotationAttributesTests.class);
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
// create the Annotations impl
|
||||
this.attributes = new SecurityAnnotationAttributes();
|
||||
}
|
||||
|
||||
public void testGenericsSuperclassDeclarationsAreIncludedWhenSubclassesOverride() {
|
||||
Method method = null;
|
||||
|
||||
try {
|
||||
method = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[] {Department.class});
|
||||
} catch (NoSuchMethodException unexpected) {
|
||||
fail("Should be a superMethod called 'someUserMethod3' on class!");
|
||||
}
|
||||
|
||||
Collection attrs = this.attributes.getAttributes(method);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("attrs: ");
|
||||
logger.debug(attrs);
|
||||
}
|
||||
|
||||
assertNotNull(attrs);
|
||||
|
||||
// expect 1 attribute
|
||||
assertTrue("Did not find 1 attribute", attrs.size() == 1);
|
||||
|
||||
// should have 1 SecurityConfig
|
||||
for (Object obj : attrs) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
|
||||
}
|
||||
|
||||
Method superMethod = null;
|
||||
|
||||
try {
|
||||
superMethod = DepartmentServiceImpl.class.getMethod("someUserMethod3", new Class[] {Entity.class});
|
||||
} catch (NoSuchMethodException unexpected) {
|
||||
fail("Should be a superMethod called 'someUserMethod3' on class!");
|
||||
}
|
||||
|
||||
System.out.println(superMethod);
|
||||
|
||||
Collection superAttrs = this.attributes.getAttributes(superMethod);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("superAttrs: ");
|
||||
logger.debug(superAttrs);
|
||||
}
|
||||
|
||||
assertNotNull(superAttrs);
|
||||
|
||||
// TODO: Enable this part of the test once we can build against Spring 2.0+ and above only (SEC-274)
|
||||
/*
|
||||
// expect 1 attribute
|
||||
assertTrue("Did not find 1 attribute", superAttrs.size() == 1);
|
||||
// should have 1 SecurityConfig
|
||||
for (Object obj : superAttrs) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
assertEquals("Found an incorrect role", "ROLE_ADMIN", sc.getAttribute());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void testGetAttributesClass() {
|
||||
Collection attrs = this.attributes.getAttributes(BusinessService.class);
|
||||
|
||||
assertNotNull(attrs);
|
||||
|
||||
// expect 1 annotation
|
||||
assertTrue(attrs.size() == 1);
|
||||
|
||||
// should have 1 SecurityConfig
|
||||
SecurityConfig sc = (SecurityConfig) attrs.iterator().next();
|
||||
|
||||
assertTrue(sc.getAttribute().equals("ROLE_USER"));
|
||||
}
|
||||
|
||||
public void testGetAttributesClassClass() {
|
||||
try {
|
||||
this.attributes.getAttributes(BusinessService.class, null);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testGetAttributesField() {
|
||||
try {
|
||||
Field field = null;
|
||||
this.attributes.getAttributes(field);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testGetAttributesFieldClass() {
|
||||
try {
|
||||
Field field = null;
|
||||
this.attributes.getAttributes(field, null);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
|
||||
public void testGetAttributesMethod() {
|
||||
Method method = null;
|
||||
|
||||
try {
|
||||
method = BusinessService.class.getMethod("someUserAndAdminMethod", new Class[] {});
|
||||
} catch (NoSuchMethodException unexpected) {
|
||||
fail("Should be a method called 'someUserAndAdminMethod' on class!");
|
||||
}
|
||||
|
||||
Collection attrs = this.attributes.getAttributes(method);
|
||||
|
||||
assertNotNull(attrs);
|
||||
|
||||
// expect 2 attributes
|
||||
assertTrue(attrs.size() == 2);
|
||||
|
||||
boolean user = false;
|
||||
boolean admin = false;
|
||||
|
||||
// should have 2 SecurityConfigs
|
||||
for (Object obj : attrs) {
|
||||
assertTrue(obj instanceof SecurityConfig);
|
||||
|
||||
SecurityConfig sc = (SecurityConfig) obj;
|
||||
|
||||
if (sc.getAttribute().equals("ROLE_USER")) {
|
||||
user = true;
|
||||
} else if (sc.getAttribute().equals("ROLE_ADMIN")) {
|
||||
admin = true;
|
||||
}
|
||||
}
|
||||
|
||||
// expect to have ROLE_USER and ROLE_ADMIN
|
||||
assertTrue(user && admin);
|
||||
}
|
||||
|
||||
public void testGetAttributesMethodClass() {
|
||||
Method method = null;
|
||||
|
||||
try {
|
||||
method = BusinessService.class.getMethod("someUserAndAdminMethod", new Class[] {});
|
||||
} catch (NoSuchMethodException unexpected) {
|
||||
fail("Should be a method called 'someUserAndAdminMethod' on class!");
|
||||
}
|
||||
|
||||
try {
|
||||
this.attributes.getAttributes(method, null);
|
||||
fail("Unsupported method should have thrown an exception!");
|
||||
} catch (UnsupportedOperationException expected) {}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation.test;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* An entity used in our generics testing.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Entity {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
String info;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public Entity(String info) {
|
||||
Assert.hasText(info, "Some information must be given!");
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
void makeLowercase() {
|
||||
this.info = info.toLowerCase();
|
||||
}
|
||||
|
||||
void makeUppercase() {
|
||||
this.info = info.toUpperCase();
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation.test;
|
||||
|
||||
/**
|
||||
* An extended version of <code>Entity</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Organisation extends Entity {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private boolean active = true;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public Organisation(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
void deactive() {
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation.test;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author $author$
|
||||
* @version $Revision: 1496 $
|
||||
*/
|
||||
public interface OrganisationService extends Service<Organisation> {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void deactive(Organisation org);
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation.test;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author $author$
|
||||
* @version $Revision: 1496 $
|
||||
*/
|
||||
public class OrganisationServiceImpl extends ServiceImpl<Organisation> implements OrganisationService {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void deactive(Organisation org) {
|
||||
org.deactive();
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* 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 org.acegisecurity.annotation.test;
|
||||
|
||||
/**
|
||||
* An extended version of <code>Entity</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Person extends Entity {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private boolean active = true;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public Person(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
void deactive() {
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user