<commit_before>Security Library
====
[![Build Status](https://api.travis-ci.org/bednar/security.png?branch=master)](https://travis-ci.org/bednar/security) [![Coverage Status](https://coveralls.io/repos/bednar/security/badge.png)](https://coveralls.io/r/bednar/security)

## Authorize Persist Events

Persist events -
[save](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/SaveEvent.java),
[read](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/ReadEvent.java),
[delete](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/DeleteEvent.java),
[list](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/ListEvent.java)
are protected by [authorization subquery](https://github.com/bednar/security/blob/master/src/main/java/com/github/bednar/security/contract/ResourceAuthorize.java).

### Create New

Criterion for select [Authenticable Resource](https://github.com/bednar/security/blob/master/src/main/java/com/github/bednar/security/contract/Authenticable.java) which can create `Chat Room`.

    /**
     * Only account with principal (unique user identifier)  Admin can create new Chat Room
     */
    @Nonnull
    public Criterion createNew(@Nonnull final String principal)
    {
        return Restrictions.eq("account", "admin");
    }
    
### Update

Criterion for select `Resources` which can `principal` update.

    /**
     * Principal (unique user identifier) can update Chat Rooms where is admin.
     */
    @Nonnull
    public Criterion update(@Nonnull final String principal)
    {
        return Restrictions.eq("admin", principal);
    }
    
### Read

Criterion for select `Resources` which can `principal` read (list).

    /**
     * Principal (unique user identifier) can read Chat Rooms where is admin or is subscribed to in.
     */
    @Nonnull
    public Criterion read(@Nonnull final String principal)
    {
        DetachedCriteria subscribers = DetachedCriteria
            .forClass(ChatRoomUserAssoc.class, "roomUser")
            .setProjection(Property.forName("chat.id"))
            .add(Restrictions.eq("user", principal));

        return Restrinctions.or(
            Restrictions.eq("admin", principal),
            Subqueries.propertyIn("id", subscribers)
        );
    }

### Delete

Criterion for select `Resources` which can `principal` delete.

    /**
     * Principal (unique user identifier) can delete Chat Rooms where is admin.
     */
    @Nonnull
    public Criterion delete(@Nonnull final String principal)
    {
        return Restrictions.eq("admin", principal);
    }

## Maven Repository

    <repository>
        <id>public</id>
        <name>Public</name><commit_msg>* Documentation about RequiresAuthentication<commit_after>Security Library
====
[![Build Status](https://api.travis-ci.org/bednar/security.png?branch=master)](https://travis-ci.org/bednar/security) [![Coverage Status](https://coveralls.io/repos/bednar/security/badge.png)](https://coveralls.io/r/bednar/security)

## Authorize Persist Events

Persist events -
[save](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/SaveEvent.java),
[read](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/ReadEvent.java),
[delete](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/DeleteEvent.java),
[list](https://github.com/bednar/persistence/blob/master/src/main/java/com/github/bednar/persistence/event/ListEvent.java)
are protected by [authorization subquery](https://github.com/bednar/security/blob/master/src/main/java/com/github/bednar/security/contract/ResourceAuthorize.java).

### Create New

Criterion for select [Authenticable Resource](https://github.com/bednar/security/blob/master/src/main/java/com/github/bednar/security/contract/Authenticable.java) which can create `Chat Room`.

    /**
     * Only account with principal (unique user identifier)  Admin can create new Chat Room
     */
    @Nonnull
    public Criterion createNew(@Nonnull final String principal)
    {
        return Restrictions.eq("account", "admin");
    }
    
### Update

Criterion for select `Resources` which can `principal` update.

    /**
     * Principal (unique user identifier) can update Chat Rooms where is admin.
     */
    @Nonnull
    public Criterion update(@Nonnull final String principal)
    {
        return Restrictions.eq("admin", principal);
    }
    
### Read

Criterion for select `Resources` which can `principal` read (list).

    /**
     * Principal (unique user identifier) can read Chat Rooms where is admin or is subscribed to in.
     */
    @Nonnull
    public Criterion read(@Nonnull final String principal)
    {
        DetachedCriteria subscribers = DetachedCriteria
            .forClass(ChatRoomUserAssoc.class, "roomUser")
            .setProjection(Property.forName("chat.id"))
            .add(Restrictions.eq("user", principal));

        return Restrinctions.or(
            Restrictions.eq("admin", principal),
            Subqueries.propertyIn("id", subscribers)
        );
    }

### Delete

Criterion for select `Resources` which can `principal` delete.

    /**
     * Principal (unique user identifier) can delete Chat Rooms where is admin.
     */
    @Nonnull
    public Criterion delete(@Nonnull final String principal)
    {
        return Restrictions.eq("admin", principal);
    }
    
## Security Annotation for API Resource

### RequiresAuthentication

[RequiresAuthentication](http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authz/annotation/RequiresAuthentication.html) 
from [Shiro](http://shiro.apache.org) can be use for annotate API Resource method which require authenticated Subject.

    @Path("/account")
    public class AccountResource implements ApiResource
    {
        @GET
        @Path("/me")
        @RequiresAuthentication
        public void me(@Nonnull @Suspend final AsynchronousResponse response)
        {
            //Subject is authenticated => generate regular response
            response.setResponse(...);
        }
    }

## Maven Repository

    <repository>
        <id>public</id>
        <name>Public</name>
{'fraction_non_alphanumeric': 0.12680477087256747, 'fraction_numerical': 0.0, 'mean_word_length': 3.4164934164934166, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, 'https://': 20, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2508362', 'n_tokens_mistral': 1837, 'n_tokens_neox': 1826, 'n_words': 380}