001/*
002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Bogdan Stefanescu
018 */
019package org.nuxeo.ecm.core.api;
020
021import java.io.Serializable;
022import java.security.Principal;
023import java.util.List;
024import java.util.UUID;
025
026import org.nuxeo.runtime.api.Framework;
027import org.nuxeo.runtime.api.login.LoginComponent;
028import org.nuxeo.runtime.services.config.ConfigurationService;
029
030/**
031 * Class to represent a principal in Nuxeo. This class holds the list of roles and groups for this principal.
032 */
033public interface NuxeoPrincipal extends Principal, Serializable {
034
035    String PREFIX = "user:";
036
037    /**
038     * @since 8.1
039     */
040    String TRANSIENT_USER_PREFIX = "transient/";
041
042    /**
043     * @since 8.1
044     * @deprecated since 10.3.
045     */
046    @Deprecated
047    String TRANSIENT_USER_FORMAT = TRANSIENT_USER_PREFIX + "%s/%s";
048
049    /**
050     * Property that defines if a transient username should be unique no matter what base username is provided, or if a
051     * transient username should be always the same for a given base username.
052     *
053     * @since 10.3
054     */
055    String TRANSIENT_USERNAME_UNIQUE_PROP = "nuxeo.transient.username.unique";
056
057    /**
058     * Gets the first name of this principal.
059     *
060     * @return the first name of this principal
061     */
062    String getFirstName();
063
064    /**
065     * Gets the last name of this principal.
066     *
067     * @return the last name of this principal
068     */
069    String getLastName();
070
071    /**
072     * Gets the password of this principal.
073     * <p>
074     * Note: Some APIs that return principals from the database intentionally do not fill this field
075     *
076     * @return the password of this principal
077     */
078    String getPassword();
079
080    /**
081     * Gets the company name of this principal.
082     *
083     * @return the company name
084     */
085    String getCompany();
086
087    /**
088     * Get the user email if any. Return null if not email was specified
089     *
090     * @return the user email or null if none
091     */
092    String getEmail();
093
094    /**
095     * Gets the groups this principal is directly member of.
096     *
097     * @return the list of the groups
098     */
099    List<String> getGroups();
100
101    /**
102     * Gets the groups this principal directly or undirectly is member of.
103     *
104     * @return the list of the groups
105     */
106    List<String> getAllGroups();
107
108    /**
109     * Recursively test if the user is member of this group.
110     *
111     * @param group The name of the group
112     */
113    boolean isMemberOf(String group);
114
115    /**
116     * Gets the roles for this principal.
117     *
118     * @return the list of the roles
119     */
120    List<String> getRoles();
121
122    void setName(String name);
123
124    void setFirstName(String firstName);
125
126    void setLastName(String lastName);
127
128    void setGroups(List<String> groups);
129
130    void setRoles(List<String> roles);
131
132    void setCompany(String company);
133
134    void setPassword(String password);
135
136    void setEmail(String email);
137
138    /**
139     * Returns a generated id that is unique for each principal instance.
140     *
141     * @return a unique string
142     */
143    String getPrincipalId();
144
145    /**
146     * Sets the principalId.
147     *
148     * @param principalId a new principalId for this instance
149     */
150    void setPrincipalId(String principalId);
151
152    DocumentModel getModel();
153
154    void setModel(DocumentModel model);
155
156    /**
157     * Returns true if the principal is an administrator.
158     * <p>
159     * Security checks still apply on the repository for administrator user. If user is a system user, this method will
160     * return true.
161     *
162     * @return true if the principal is an administrator.
163     */
164    boolean isAdministrator();
165
166    /**
167     * Returns the {@code tenantId} of this {@link NuxeoPrincipal}, or {@code null} if there is no {@code tenantId}.
168     *
169     * @since 5.6
170     */
171    String getTenantId();
172
173    /**
174     * Checks if the principal is anonymous (guest user).
175     *
176     * @return true if the principal is anonymous.
177     */
178    boolean isAnonymous();
179
180    /**
181     * Gets the base user from which this principal was created, or {@code null} if this principal was not created from
182     * another user.
183     *
184     * @return the originating user, or {@code null}
185     */
186    String getOriginatingUser();
187
188    /**
189     * Sets the originating user.
190     *
191     * @param originatingUser the originating user
192     */
193    void setOriginatingUser(String originatingUser);
194
195    /**
196     * Gets the acting user for this principal.
197     * <p>
198     * This is the originating user (usually when this principal is a system user), or if there is none this principal's
199     * user.
200     *
201     * @return the acting user
202     * @since 6.0
203     */
204    String getActingUser();
205
206    /**
207     * Returns true if the principal is a transient principal.
208     *
209     * @since 8.1
210     */
211    boolean isTransient();
212
213    /**
214     * Returns true if the given @{code username} is a transient username.
215     *
216     * @since 8.1
217     */
218    static boolean isTransientUsername(String username) {
219        return username != null && username.startsWith(TRANSIENT_USER_PREFIX);
220    }
221
222    /**
223     * Computes a transient username from the given {@code baseUsername}.
224     * <p>
225     * If the configuration property {@value #TRANSIENT_USERNAME_UNIQUE_PROP} is {@code true}, the transient username
226     * will be unique, otherwise it will always be the same for a given {@code baseUsername}.
227     *
228     * @since 8.1
229     */
230    static String computeTransientUsername(String baseUsername) {
231        if (baseUsername != null && !baseUsername.startsWith(TRANSIENT_USER_PREFIX)) {
232            StringBuilder sb = new StringBuilder(TRANSIENT_USER_PREFIX);
233            sb.append(baseUsername);
234            if (Framework.getService(ConfigurationService.class).isBooleanTrue(TRANSIENT_USERNAME_UNIQUE_PROP)) {
235                String uuid = UUID.randomUUID().toString();
236                uuid = uuid.replaceAll("-", "").substring(0, 16);
237                sb.append("/");
238                sb.append(uuid);
239            }
240            return sb.toString();
241        }
242        return baseUsername;
243    }
244
245    /**
246     * Returns the current logged in {@link NuxeoPrincipal}.
247     *
248     * @return the current logged in {@link NuxeoPrincipal}, or {@code null} if there is none
249     * @since 11.1
250     */
251    static NuxeoPrincipal getCurrent() {
252        Principal principal = LoginComponent.getCurrentPrincipal();
253        if (principal instanceof NuxeoPrincipal) {
254            return (NuxeoPrincipal) principal;
255        } else if (LoginComponent.isSystemLogin(principal)) {
256            return new SystemPrincipal(principal.getName());
257        } else {
258            return null;
259        }
260    }
261
262    /**
263     * Checks if the current logged in {@link NuxeoPrincipal} is an Administrator.
264     *
265     * @return {@code true} if the current logged in {@link NuxeoPrincipal} is an Administrator
266     * @since 11.1
267     */
268    static boolean isCurrentAdministrator() {
269        NuxeoPrincipal principal = getCurrent();
270        return principal != null && principal.isAdministrator();
271    }
272
273}