1 /**
2 * Copyright (c) 2012-2017, s3auth.com
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 s3auth.com 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 com.s3auth.hosts;
31
32 import com.jcabi.aspects.Immutable;
33 import com.jcabi.urn.URN;
34 import java.lang.annotation.Documented;
35 import java.lang.annotation.ElementType;
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 import java.lang.annotation.Target;
39 import java.net.URI;
40 import javax.validation.Constraint;
41 import javax.validation.ConstraintValidator;
42 import javax.validation.ConstraintValidatorContext;
43 import javax.validation.Payload;
44
45 /**
46 * Single user.
47 *
48 * <p>Implementation must be immutable and thread-safe.
49 *
50 * @author Yegor Bugayenko (yegor@tpc2.com)
51 * @version $Id: c0f8e516dd921c3e470cd1d31d5f32305f458df0 $
52 * @since 0.0.1
53 */
54 @User.Valid
55 @Immutable
56 public interface User {
57
58 /**
59 * Anonymous User.
60 */
61 User ANONYMOUS = new User() {
62 @Override
63 public URN identity() {
64 return URN.create("urn:anonymous:0");
65 }
66 @Override
67 public String name() {
68 return "Mr. Anonymous";
69 }
70 @Override
71 public URI photo() {
72 return URI.create("http://img.s3auth.com/unknown.png");
73 }
74 };
75
76 /**
77 * Unique name of it.
78 * @return Unique name as URN
79 */
80 URN identity();
81
82 /**
83 * Full name to display.
84 * @return Full name
85 */
86 String name();
87
88 /**
89 * Photo.
90 * @return URL of the image
91 */
92 URI photo();
93
94 @Target(ElementType.TYPE)
95 @Retention(RetentionPolicy.RUNTIME)
96 @Constraint(validatedBy = User.Validator.class)
97 @Documented
98 public @interface Valid {
99 /**
100 * Message of the validation error.
101 */
102 String message() default "invalid user";
103 /**
104 * Groups.
105 */
106 Class<?>[] groups() default { };
107 /**
108 * Payload.
109 */
110 Class<? extends Payload>[] payload() default { };
111 }
112
113 /**
114 * Validator of User.
115 */
116 class Validator implements ConstraintValidator<User.Valid, User> {
117 @Override
118 public void initialize(final User.Valid annotation) {
119 //nothing to do
120 }
121 /**
122 * {@inheritDoc}
123 * @checkstyle MultipleStringLiterals (50 lines)
124 */
125 @Override
126 public boolean isValid(final User user,
127 final ConstraintValidatorContext ctx) {
128 boolean isValid = true;
129 final String nid = user.identity().nid();
130 if (!"facebook".equals(nid)
131 && !"google".equals(nid)
132 && !"github".equals(nid)
133 && !"test".equals(nid)) {
134 ctx.buildConstraintViolationWithTemplate(
135 String.format("invalid NID of URN: %s", user.identity())
136 ).addPropertyNode("identity").addConstraintViolation();
137 isValid = false;
138 }
139 if (!user.identity().nss().matches("\\d+")) {
140 ctx.buildConstraintViolationWithTemplate(
141 String.format("invalid NSS of URN: %s", user.identity())
142 ).addPropertyNode("identity").addConstraintViolation();
143 isValid = false;
144 }
145 return isValid;
146 }
147 }
148
149 }