New AAA CLI standalone JAR to create users and set passwords
[aaa.git] / aaa-authn-api / src / main / java / org / opendaylight / aaa / api / StoreBuilder.java
1 /*
2  * Copyright (c) 2014, 2016 Hewlett-Packard Development Company, L.P. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.aaa.api;
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import org.opendaylight.aaa.api.model.Domain;
16 import org.opendaylight.aaa.api.model.Grant;
17 import org.opendaylight.aaa.api.model.Role;
18 import org.opendaylight.aaa.api.model.User;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * StoreBuilder is triggered during feature installation by
24  * <code>AAAIDMLightModule.createInstance()</code>. StoreBuilder is responsible
25  * for initializing the IIDMStore with initial default user account
26  * information. By default, the following users are created:
27  * <ol>
28  * <li>admin</li>
29  * <li>user</li>
30  * </ol>
31  *
32  * <p>By default, the following domain is created:
33  * <ol>
34  * <li>sdn</li>
35  * </ol>
36  *
37  * <p>By default, the following grants are created:
38  * <ol>
39  * <li>admin with admin role on sdn</li>
40  * <li>admin with user role on sdn</li>
41  * <li>user with user role on sdn</li>
42  * </ol>
43  *
44  * @author peter.mellquist@hp.com
45  * @author saichler@cisco.com
46  * @author Michael Vorburger.ch - some refactoring, for new CLI tool
47  */
48 public class StoreBuilder {
49
50     private static final Logger LOG = LoggerFactory.getLogger(StoreBuilder.class);
51
52     private final IIDMStore store;
53
54     public StoreBuilder(IIDMStore store) {
55         this.store = store;
56     }
57
58     /**
59      * Initialize IIDMStore with some default entries.
60      *
61      * @deprecated Better explicitly use
62      *             {@link #initDomainAndRolesWithoutUsers(String)} or
63      *             {@link #initWithDefaultUsers(String)}
64      *
65      * @throws IDMStoreException for issues coming from the IIDMStore
66      */
67     @Deprecated
68     public void init() throws IDMStoreException {
69         initWithDefaultUsers(IIDMStore.DEFAULT_DOMAIN);
70     }
71
72     /**
73      * Initialize IIDMStore with the default domain and the 'user' and 'admin' roles, if needed.
74      * This does not create any default user entries (because they are an inherent security risk).
75      *
76      * @param domainID ID (same as name) of the "authentication domain"
77      * @return ID of the just newly created Domain, or null if no new one had to be created
78      * @return true if initialization took place, false if it wasn't needed
79      * @throws IDMStoreException for issues coming from the IIDMStore
80      */
81     public String initDomainAndRolesWithoutUsers(String domainID) throws IDMStoreException {
82         LOG.info("Checking if default entries must be created in IDM store");
83
84         // Check whether the default domain exists. If it exists, then do not
85         // create default data in the store.
86         // TODO Address the fact that someone may delete the sdn domain, or make
87         // sdn mandatory.
88         Domain defaultDomain = store.readDomain(domainID);
89         if (defaultDomain != null) {
90             LOG.info("Found default domain in IDM store, skipping insertion of default data");
91             return null;
92         }
93
94         // Create default domain
95         Domain domain = new Domain();
96         domain.setEnabled(true);
97         domain.setName(IIDMStore.DEFAULT_DOMAIN);
98         domain.setDescription("default odl sdn domain");
99         domain = store.writeDomain(domain);
100         LOG.info("Created default domain");
101         String newDomainID = domain.getDomainid();
102
103         // Create default Roles ("admin" and "user")
104         Role adminRole = new Role();
105         adminRole.setName("admin");
106         adminRole.setDomainid(newDomainID);
107         adminRole.setDescription("a role for admins");
108         adminRole = store.writeRole(adminRole);
109         LOG.info("Created 'admin' role");
110
111         Role userRole = new Role();
112         userRole.setName("user");
113         userRole.setDomainid(newDomainID);
114         userRole.setDescription("a role for users");
115         userRole = store.writeRole(userRole);
116         LOG.info("Created 'user' role");
117
118         return newDomainID;
119     }
120
121     /**
122      * Initialize IIDMStore with the default domain and the 'user' and 'admin'
123      * roles AND 2 default user accounts (with default passwords, which is bad practice).
124      * @param domainID ID (same as name) of the "authentication domain"
125      * @throws IDMStoreException for issues coming from the IIDMStore
126      */
127     public void initWithDefaultUsers(String domainID) throws IDMStoreException {
128         String newDomainID = initDomainAndRolesWithoutUsers(domainID);
129         if (newDomainID != null) {
130             createUser(newDomainID, "admin", "admin", true);
131             createUser(newDomainID, "user", "user", false);
132         }
133     }
134
135     public List<String> getRoleIDs(String domainID, List<String> roleNames) throws IDMStoreException {
136         Map<String, String> roleNameToID = new HashMap<>();
137         List<Role> roles = store.getRoles().getRoles();
138         for (Role role : roles) {
139             if (domainID.equals(role.getDomainid())) {
140                 roleNameToID.put(role.getName(), role.getRoleid());
141             }
142         }
143
144         List<String> roleIDs = new ArrayList<>(roleNames.size());
145         for (String roleName : roleNames) {
146             String roleID = roleNameToID.get(roleName);
147             if (roleID == null) {
148                 throw new IllegalStateException("'" + roleName + "' role not found (in domain '" + domainID + "')");
149             }
150             roleIDs.add(roleID);
151         }
152
153         return roleIDs;
154     }
155
156     /**
157      * Create new user.
158      *
159      * @param domainID ID (same as name) of the "authentication domain"
160      * @param userName new user name (without the domain prefix which gets automatically added)
161      * @param password the new user's initial password
162      * @param roleIDs list of IDs of roles to grant the new user (e.g. ["user", "admin"])
163      *
164      * @return ID of the just newly created user, useful to reference it e.g. in grants
165      * @throws IDMStoreException for issues coming from the IIDMStore
166      */
167     public String createUser(String domainID, String userName, String password, List<String> roleIDs)
168             throws IDMStoreException {
169         User newUser = new User();
170         newUser.setEnabled(true);
171         newUser.setDomainid(domainID);
172         newUser.setName(userName);
173         newUser.setDescription(userName + " user");
174         newUser.setEmail("");
175         newUser.setPassword(password);
176         newUser = store.writeUser(newUser);
177         LOG.debug("Created '" + userName + "' user in domain '" + domainID + "'");
178
179         String newUserID = newUser.getUserid();
180         for (String roleID : roleIDs) {
181             createGrant(domainID, newUserID, roleID);
182         }
183         return newUserID;
184     }
185
186     public String createUser(String domainID, String userName, String password, boolean isAdmin)
187             throws IDMStoreException {
188         List<String> roleIDs;
189         if (isAdmin) {
190             roleIDs = getRoleIDs(domainID, Arrays.asList("user", "admin"));
191         } else {
192             roleIDs = getRoleIDs(domainID, Arrays.asList("user"));
193         }
194         return createUser(domainID, userName, password, roleIDs);
195     }
196
197     private void createGrant(String domainID, String userID, String roleID) throws IDMStoreException {
198         Grant grant = new Grant();
199         grant.setDomainid(domainID);
200         grant.setUserid(userID);
201         grant.setRoleid(roleID);
202         grant = store.writeGrant(grant);
203         LOG.debug("Granted '" + userID + "' user the '" + roleID + "' role in domain '" + domainID + "'");
204     }
205 }