1 /** 2 * Copyright (c) 2014, stateful.co 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 1) Redistributions of source code must retain the above 8 * copyright notice, this list of conditions and the following 9 * disclaimer. 2) Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 3) Neither the name of the stateful.co nor 13 * the names of its contributors may be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 19 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 * OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package co.stateful.rest; 31 32 import co.stateful.spi.Base; 33 import co.stateful.spi.User; 34 import com.jcabi.urn.URN; 35 import com.rexsl.page.BaseResource; 36 import com.rexsl.page.auth.Identity; 37 import com.rexsl.page.auth.Provider; 38 import java.io.IOException; 39 import java.net.HttpURLConnection; 40 import java.net.URI; 41 import javax.ws.rs.WebApplicationException; 42 import javax.ws.rs.core.MultivaluedMap; 43 import javax.ws.rs.core.Response; 44 45 /** 46 * Authentication. 47 * 48 * <p>The class is mutable and NOT thread-safe. 49 * 50 * @author Yegor Bugayenko (yegor@tpc2.com) 51 * @version $Id$ 52 * @checkstyle ClassDataAbstractionCouplingCheck (500 lines) 53 */ 54 final class Auth implements Provider { 55 56 /** 57 * URN header. 58 */ 59 private static final String HEADER_URN = "X-Sttc-URN"; 60 61 /** 62 * Token header. 63 */ 64 private static final String HEADER_TOKEN = "X-Sttc-Token"; 65 66 /** 67 * Resource. 68 */ 69 private final transient BaseResource resource; 70 71 /** 72 * Base. 73 */ 74 private final transient Base base; 75 76 /** 77 * Ctor. 78 * @param res Resource 79 * @param bse Base 80 */ 81 Auth(final BaseResource res, final Base bse) { 82 this.resource = res; 83 this.base = bse; 84 } 85 86 @Override 87 public Identity identity() throws IOException { 88 final MultivaluedMap<String, String> headers = 89 this.resource.httpHeaders().getRequestHeaders(); 90 Identity identity = Identity.ANONYMOUS; 91 if (headers.containsKey(Auth.HEADER_URN) 92 && headers.containsKey(Auth.HEADER_TOKEN)) { 93 final URN urn = URN.create(headers.getFirst(Auth.HEADER_URN)); 94 final User user = this.base.user(urn); 95 if (!user.exists()) { 96 throw new WebApplicationException( 97 Response.status(HttpURLConnection.HTTP_UNAUTHORIZED).build() 98 ); 99 } 100 final String token = headers.getFirst(Auth.HEADER_TOKEN); 101 if (!user.token().equals(token)) { 102 throw new WebApplicationException( 103 Response.status(HttpURLConnection.HTTP_UNAUTHORIZED).build() 104 ); 105 } 106 identity = new Identity.Simple(urn, "http", URI.create("#")); 107 } 108 return identity; 109 } 110 }