#3529 feature - Added applications to user profile and upgrade to
angular4
| .. | .. |
|---|
| 10 | 10 | import javax.persistence.FetchType; |
|---|
| 11 | 11 | import javax.persistence.GeneratedValue; |
|---|
| 12 | 12 | import javax.persistence.Id; |
|---|
| 13 | +import javax.persistence.JoinColumn; |
|---|
| 14 | +import javax.persistence.JoinTable; |
|---|
| 15 | +import javax.persistence.ManyToMany; |
|---|
| 13 | 16 | import javax.persistence.NamedQueries; |
|---|
| 14 | 17 | import javax.persistence.NamedQuery; |
|---|
| 15 | 18 | import javax.persistence.OneToMany; |
|---|
| .. | .. |
|---|
| 68 | 71 | @JsonManagedReference |
|---|
| 69 | 72 | private Set<ApplicationMetadata> metadata; |
|---|
| 70 | 73 | |
|---|
| 74 | + @JsonIgnore |
|---|
| 75 | + // We don't include the users to limit the size of each row a the listing |
|---|
| 76 | + @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) |
|---|
| 77 | + @JoinTable(name = "user_application", // |
|---|
| 78 | + joinColumns = { @JoinColumn(name = "application_id", referencedColumnName = "id") }, // |
|---|
| 79 | + inverseJoinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") }) |
|---|
| 80 | + private Set<User> users; |
|---|
| 81 | + |
|---|
| 71 | 82 | public Integer getId() { |
|---|
| 72 | 83 | return id; |
|---|
| 73 | 84 | } |
|---|
| .. | .. |
|---|
| 43 | 43 | @NamedQueries({ @NamedQuery(name = "list-packs", query = "SELECT pa FROM Pack pa"), // |
|---|
| 44 | 44 | @NamedQuery(name = "pack-by-code", query = "SELECT pa FROM Pack pa where pa.code = :code"), // |
|---|
| 45 | 45 | @NamedQuery(name = "list-packs-by-lic-type", query = "SELECT pa FROM Pack pa where pa.licenseType.id = :lt_id"), // |
|---|
| 46 | + @NamedQuery(name = "list-packs-by-orgs-apps", query = "SELECT pa FROM Pack pa where pa.organization.id in :list_ids_org and pa.licenseType.application.id in :list_ids_app "), // |
|---|
| 46 | 47 | @NamedQuery(name = "list-packs-by-orgs", query = "SELECT pa FROM Pack pa where pa.organization.id in :list_ids") }) |
|---|
| 47 | 48 | public class Pack implements Serializable { |
|---|
| 48 | 49 | |
|---|
| .. | .. |
|---|
| 2 | 2 | |
|---|
| 3 | 3 | import java.io.Serializable; |
|---|
| 4 | 4 | import java.util.ArrayList; |
|---|
| 5 | +import java.util.Collection; |
|---|
| 5 | 6 | import java.util.Date; |
|---|
| 6 | 7 | import java.util.HashSet; |
|---|
| 7 | 8 | import java.util.List; |
|---|
| 8 | 9 | import java.util.Set; |
|---|
| 10 | +import java.util.stream.Collectors; |
|---|
| 9 | 11 | |
|---|
| 10 | 12 | import javax.persistence.Column; |
|---|
| 11 | 13 | import javax.persistence.Entity; |
|---|
| .. | .. |
|---|
| 76 | 78 | inverseJoinColumns = { @JoinColumn(name = "organization_id", referencedColumnName = "id") } // |
|---|
| 77 | 79 | ) |
|---|
| 78 | 80 | private Set<Organization> organizations; |
|---|
| 81 | + |
|---|
| 82 | + @JsonIgnore |
|---|
| 83 | + @ManyToMany |
|---|
| 84 | + @JoinTable(name = "user_application", // |
|---|
| 85 | + joinColumns = { @JoinColumn(name = "username", referencedColumnName = "username") }, // |
|---|
| 86 | + inverseJoinColumns = { @JoinColumn(name = "application_id", referencedColumnName = "id") } // |
|---|
| 87 | + ) |
|---|
| 88 | + private Set<Application> applications; |
|---|
| 79 | 89 | |
|---|
| 80 | 90 | public String getUsername() { |
|---|
| 81 | 91 | return username; |
|---|
| .. | .. |
|---|
| 182 | 192 | this.organizations = organizations; |
|---|
| 183 | 193 | } |
|---|
| 184 | 194 | |
|---|
| 195 | + public Set<Application> getApplications() { |
|---|
| 196 | + return applications; |
|---|
| 197 | + } |
|---|
| 198 | + |
|---|
| 199 | + public void setApplications(Set<Application> applications) { |
|---|
| 200 | + this.applications = applications; |
|---|
| 201 | + } |
|---|
| 202 | + |
|---|
| 185 | 203 | @JsonProperty("organizations_ids") |
|---|
| 186 | 204 | public void setOrgsIds(List<Integer> orgsIds) { |
|---|
| 187 | 205 | organizations = new HashSet<>(); |
|---|
| .. | .. |
|---|
| 204 | 222 | return ids; |
|---|
| 205 | 223 | } |
|---|
| 206 | 224 | |
|---|
| 225 | + @JsonProperty("applications_ids") |
|---|
| 226 | + public void setAppsIds(Collection<Integer> appIds) { |
|---|
| 227 | + applications = new HashSet<>(); |
|---|
| 228 | + for (Integer appid : appIds) { |
|---|
| 229 | + Application a = new Application(); |
|---|
| 230 | + a.setId(appid); |
|---|
| 231 | + applications.add(a); |
|---|
| 232 | + } |
|---|
| 233 | + } |
|---|
| 234 | + |
|---|
| 235 | + @JsonProperty("applications_ids") |
|---|
| 236 | + public Set<Integer> getAppsIds() { |
|---|
| 237 | + if (applications == null) { |
|---|
| 238 | + return null; |
|---|
| 239 | + } |
|---|
| 240 | + Set<Integer> ids = new HashSet<>(); |
|---|
| 241 | + for (Application app : applications) { |
|---|
| 242 | + ids.add(app.getId()); |
|---|
| 243 | + } |
|---|
| 244 | + return ids; |
|---|
| 245 | + } |
|---|
| 246 | + |
|---|
| 207 | 247 | @JsonIgnore |
|---|
| 208 | 248 | public Set<Integer> getAllOrgsIds() { |
|---|
| 209 | 249 | if (organizations == null) { |
|---|
| .. | .. |
|---|
| 214 | 254 | return ids; |
|---|
| 215 | 255 | } |
|---|
| 216 | 256 | |
|---|
| 257 | + @JsonIgnore |
|---|
| 258 | + public Set<Integer> getAllAppsIds() { |
|---|
| 259 | + if (applications == null) { |
|---|
| 260 | + return null; |
|---|
| 261 | + } |
|---|
| 262 | + Set<Integer> ids = this.applications.parallelStream().map(app -> app.getId()).collect(Collectors.toSet()); |
|---|
| 263 | + |
|---|
| 264 | + return ids; |
|---|
| 265 | + } |
|---|
| 266 | + |
|---|
| 267 | + /** |
|---|
| 268 | + * Walk into the organization hierarchy to include all descendants |
|---|
| 269 | + * |
|---|
| 270 | + * @param list |
|---|
| 271 | + * @param orgIds |
|---|
| 272 | + */ |
|---|
| 217 | 273 | private void includeAllOrgs(Set<Organization> list, Set<Integer> orgIds) { |
|---|
| 218 | 274 | for (Organization org : list) { |
|---|
| 219 | 275 | orgIds.add(org.getId()); |
|---|
| .. | .. |
|---|
| 229 | 285 | this.email = email; |
|---|
| 230 | 286 | } |
|---|
| 231 | 287 | |
|---|
| 288 | + /** |
|---|
| 289 | + * Numeric rol mask. Be aware to use different bit position for each role |
|---|
| 290 | + * |
|---|
| 291 | + * @author rob |
|---|
| 292 | + */ |
|---|
| 232 | 293 | public static class Rol { |
|---|
| 233 | 294 | public static final int ADVANCE = 0x01; |
|---|
| 234 | 295 | public static final int ADMIN = 0x02; |
|---|
| 235 | | - public static final int[] ALL = new int[] { ADVANCE, ADMIN }; |
|---|
| 296 | + public static final int BASIC = 0x04; |
|---|
| 297 | + public static final int[] ALL = new int[] { ADVANCE, ADMIN, BASIC }; |
|---|
| 236 | 298 | } |
|---|
| 237 | 299 | |
|---|
| 238 | 300 | } |
|---|
| .. | .. |
|---|
| 21 | 21 | import javax.ws.rs.ext.WriterInterceptor; |
|---|
| 22 | 22 | import javax.ws.rs.ext.WriterInterceptorContext; |
|---|
| 23 | 23 | |
|---|
| 24 | | -import net.curisit.securis.db.User; |
|---|
| 25 | | -import net.curisit.securis.security.BasicSecurityContext; |
|---|
| 26 | | -import net.curisit.securis.security.Securable; |
|---|
| 27 | | -import net.curisit.securis.utils.CacheTTL; |
|---|
| 28 | | -import net.curisit.securis.utils.TokenHelper; |
|---|
| 29 | | - |
|---|
| 30 | 24 | import org.apache.logging.log4j.LogManager; |
|---|
| 31 | 25 | import org.apache.logging.log4j.Logger; |
|---|
| 32 | 26 | import org.jboss.resteasy.core.Dispatcher; |
|---|
| .. | .. |
|---|
| 36 | 30 | import org.jboss.resteasy.spi.HttpRequest; |
|---|
| 37 | 31 | import org.jboss.resteasy.spi.ResteasyProviderFactory; |
|---|
| 38 | 32 | |
|---|
| 33 | +import net.curisit.securis.db.User; |
|---|
| 34 | +import net.curisit.securis.security.BasicSecurityContext; |
|---|
| 35 | +import net.curisit.securis.security.Securable; |
|---|
| 36 | +import net.curisit.securis.utils.CacheTTL; |
|---|
| 37 | +import net.curisit.securis.utils.TokenHelper; |
|---|
| 38 | + |
|---|
| 39 | 39 | @Provider |
|---|
| 40 | 40 | @Priority(Priorities.AUTHENTICATION) |
|---|
| 41 | 41 | public class RequestsInterceptor implements ContainerRequestFilter, WriterInterceptor { |
|---|
| 42 | | - private static final Logger LOG = LogManager.getLogger(RequestsInterceptor.class); |
|---|
| 42 | + private static final Logger LOG = LogManager.getLogger(RequestsInterceptor.class); |
|---|
| 43 | 43 | |
|---|
| 44 | | - @Context |
|---|
| 45 | | - private HttpServletResponse servletResponse; |
|---|
| 44 | + @Context |
|---|
| 45 | + private HttpServletResponse servletResponse; |
|---|
| 46 | 46 | |
|---|
| 47 | | - @Context |
|---|
| 48 | | - private HttpServletRequest servletRequest; |
|---|
| 47 | + @Context |
|---|
| 48 | + private HttpServletRequest servletRequest; |
|---|
| 49 | 49 | |
|---|
| 50 | | - @Inject |
|---|
| 51 | | - private CacheTTL cache; |
|---|
| 50 | + @Inject |
|---|
| 51 | + private CacheTTL cache; |
|---|
| 52 | 52 | |
|---|
| 53 | | - @Inject |
|---|
| 54 | | - private TokenHelper tokenHelper; |
|---|
| 53 | + @Inject |
|---|
| 54 | + private TokenHelper tokenHelper; |
|---|
| 55 | 55 | |
|---|
| 56 | | - @Context |
|---|
| 57 | | - private Dispatcher dispatcher; |
|---|
| 56 | + @Context |
|---|
| 57 | + private Dispatcher dispatcher; |
|---|
| 58 | 58 | |
|---|
| 59 | | - @Inject |
|---|
| 60 | | - private EntityManagerProvider emProvider; |
|---|
| 59 | + @Inject |
|---|
| 60 | + private EntityManagerProvider emProvider; |
|---|
| 61 | 61 | |
|---|
| 62 | | - @Override |
|---|
| 63 | | - public void filter(ContainerRequestContext containerRequestContext) throws IOException { |
|---|
| 64 | | - EntityManager em = emProvider.getEntityManager(); |
|---|
| 65 | | - LOG.debug("GETTING EM: {}", em); |
|---|
| 62 | + @Override |
|---|
| 63 | + public void filter(ContainerRequestContext containerRequestContext) throws IOException { |
|---|
| 64 | + EntityManager em = emProvider.getEntityManager(); |
|---|
| 65 | + LOG.debug("GETTING EM: {}", em); |
|---|
| 66 | 66 | |
|---|
| 67 | | - ResteasyProviderFactory.pushContext(EntityManager.class, em); |
|---|
| 67 | + ResteasyProviderFactory.pushContext(EntityManager.class, em); |
|---|
| 68 | 68 | |
|---|
| 69 | | - ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext |
|---|
| 70 | | - .getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"); |
|---|
| 71 | | - Method method = methodInvoker.getMethod(); |
|---|
| 69 | + ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) containerRequestContext.getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"); |
|---|
| 70 | + Method method = methodInvoker.getMethod(); |
|---|
| 72 | 71 | |
|---|
| 73 | | - LOG.debug("Stored in context, em: {}, {}", em, method.toGenericString()); |
|---|
| 72 | + LOG.debug("Stored in context, em: {}, {}", em, method.toGenericString()); |
|---|
| 74 | 73 | |
|---|
| 75 | | - boolean next = checkSecurableMethods(containerRequestContext, method); |
|---|
| 76 | | - if (next) { |
|---|
| 77 | | - prepareTransaction(containerRequestContext, method, em); |
|---|
| 78 | | - } |
|---|
| 79 | | - } |
|---|
| 74 | + boolean next = checkSecurableMethods(containerRequestContext, method); |
|---|
| 75 | + if (next) { |
|---|
| 76 | + prepareTransaction(containerRequestContext, method, em); |
|---|
| 77 | + } |
|---|
| 78 | + } |
|---|
| 80 | 79 | |
|---|
| 81 | | - private void prepareTransaction(ContainerRequestContext containerRequestContext, Method method, EntityManager em) { |
|---|
| 80 | + private void prepareTransaction(ContainerRequestContext containerRequestContext, Method method, EntityManager em) { |
|---|
| 82 | 81 | |
|---|
| 83 | | - if (method.isAnnotationPresent(EnsureTransaction.class)) { |
|---|
| 84 | | - LOG.debug("Beginning a new transaction"); |
|---|
| 85 | | - em.getTransaction().begin(); |
|---|
| 86 | | - } |
|---|
| 87 | | - } |
|---|
| 82 | + if (method.isAnnotationPresent(EnsureTransaction.class)) { |
|---|
| 83 | + LOG.debug("Beginning a new transaction"); |
|---|
| 84 | + em.getTransaction().begin(); |
|---|
| 85 | + } |
|---|
| 86 | + } |
|---|
| 88 | 87 | |
|---|
| 89 | | - private boolean checkSecurableMethods(ContainerRequestContext containerRequestContext, Method method) { |
|---|
| 90 | | - if (!method.isAnnotationPresent(Securable.class)) { |
|---|
| 91 | | - return true; |
|---|
| 92 | | - } |
|---|
| 93 | | - String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM); |
|---|
| 94 | | - if (token == null || !tokenHelper.isTokenValid(token)) { |
|---|
| 95 | | - LOG.warn("Access denied, Token not valid: {} for method: {}::{}", token, method.getDeclaringClass(), method.getName()); |
|---|
| 96 | | - containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build()); |
|---|
| 97 | | - return false; |
|---|
| 98 | | - } else { |
|---|
| 88 | + private boolean checkSecurableMethods(ContainerRequestContext containerRequestContext, Method method) { |
|---|
| 89 | + if (!method.isAnnotationPresent(Securable.class)) { |
|---|
| 90 | + return true; |
|---|
| 91 | + } |
|---|
| 92 | + String token = servletRequest.getHeader(TokenHelper.TOKEN_HEADER_PÀRAM); |
|---|
| 93 | + if (token == null || !tokenHelper.isTokenValid(token)) { |
|---|
| 94 | + LOG.warn("Access denied, Token not valid: {} for method: {}::{}", token, method.getDeclaringClass(), method.getName()); |
|---|
| 95 | + containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build()); |
|---|
| 96 | + return false; |
|---|
| 97 | + } else { |
|---|
| 98 | + Securable securable = method.getAnnotation(Securable.class); |
|---|
| 99 | + // If roles == 0 we only need to validate the token |
|---|
| 100 | + String username = tokenHelper.extractUserFromToken(token); |
|---|
| 101 | + int userRoles = getUserRoles(username); |
|---|
| 102 | + if (securable.roles() != 0 && (securable.roles() & userRoles) == 0) { |
|---|
| 103 | + LOG.warn("Method {} requires roles: {}, but user {} hasn't got them", method.getName(), securable.roles(), username); |
|---|
| 104 | + containerRequestContext.abortWith(Response.status(Status.UNAUTHORIZED).build()); |
|---|
| 105 | + return false; |
|---|
| 106 | + } |
|---|
| 107 | + Set<Integer> orgs = getUserOrganizations(username); |
|---|
| 108 | + Set<Integer> apps = getUserApplications(username); |
|---|
| 99 | 109 | |
|---|
| 100 | | - // If roles == 0 we only need to validate the token |
|---|
| 101 | | - String username = tokenHelper.extractUserFromToken(token); |
|---|
| 102 | | - int userRoles = getUserRoles(username); |
|---|
| 103 | | - Set<Integer> orgs = getUserOrganizations(username); |
|---|
| 110 | + BasicSecurityContext scw = new BasicSecurityContext(username, userRoles, servletRequest.isSecure()); |
|---|
| 111 | + scw.setOrganizationsIds(orgs); |
|---|
| 112 | + scw.setApplicationsIds(apps); |
|---|
| 113 | + containerRequestContext.setSecurityContext(scw); |
|---|
| 114 | + // Next line provide injection in resource methods |
|---|
| 115 | + ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw); |
|---|
| 116 | + LOG.debug("Added custom SecurityContext for user {}, orgs: {}", username, orgs); |
|---|
| 117 | + } |
|---|
| 118 | + return true; |
|---|
| 104 | 119 | |
|---|
| 105 | | - BasicSecurityContext scw = new BasicSecurityContext(username, userRoles, servletRequest.isSecure()); |
|---|
| 106 | | - scw.setOrganizationsIds(orgs); |
|---|
| 107 | | - containerRequestContext.setSecurityContext(scw); |
|---|
| 108 | | - // Next line provide injection in resource methods |
|---|
| 109 | | - ResteasyProviderFactory.pushContext(BasicSecurityContext.class, scw); |
|---|
| 110 | | - LOG.debug("Added custom SecurityContext for user {}, orgs: {}", username, orgs); |
|---|
| 111 | | - } |
|---|
| 112 | | - return true; |
|---|
| 120 | + } |
|---|
| 113 | 121 | |
|---|
| 114 | | - } |
|---|
| 122 | + private Set<Integer> getUserOrganizations(String username) { |
|---|
| 123 | + @SuppressWarnings("unchecked") |
|---|
| 124 | + Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class); |
|---|
| 125 | + if (userOrgs == null) { |
|---|
| 126 | + EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 115 | 127 | |
|---|
| 116 | | - private Set<Integer> getUserOrganizations(String username) { |
|---|
| 117 | | - @SuppressWarnings("unchecked") |
|---|
| 118 | | - Set<Integer> userOrgs = cache.get("orgs_" + username, Set.class); |
|---|
| 119 | | - if (userOrgs == null) { |
|---|
| 120 | | - EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 128 | + // Theorically this shouldn't be never null, but just in case... |
|---|
| 129 | + User user = em.find(User.class, username); |
|---|
| 130 | + if (user != null) { |
|---|
| 131 | + userOrgs = user.getAllOrgsIds(); |
|---|
| 132 | + // We store user orgs in cache only for one hour |
|---|
| 133 | + cache.set("orgs_" + username, userOrgs, 3600); |
|---|
| 134 | + } |
|---|
| 135 | + } |
|---|
| 121 | 136 | |
|---|
| 122 | | - // Theorically this shouldn't be never null, but just in case... |
|---|
| 123 | | - User user = em.find(User.class, username); |
|---|
| 124 | | - if (user != null) { |
|---|
| 125 | | - userOrgs = user.getAllOrgsIds(); |
|---|
| 126 | | - // We store user orgs in cache only for one hour |
|---|
| 127 | | - cache.set("orgs_" + username, userOrgs, 3600); |
|---|
| 128 | | - } |
|---|
| 129 | | - } |
|---|
| 137 | + return userOrgs; |
|---|
| 138 | + } |
|---|
| 130 | 139 | |
|---|
| 131 | | - return userOrgs; |
|---|
| 132 | | - } |
|---|
| 140 | + private Set<Integer> getUserApplications(String username) { |
|---|
| 141 | + @SuppressWarnings("unchecked") |
|---|
| 142 | + Set<Integer> userApps = cache.get("apps_" + username, Set.class); |
|---|
| 143 | + if (userApps == null) { |
|---|
| 144 | + EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 133 | 145 | |
|---|
| 134 | | - private int getUserRoles(String username) { |
|---|
| 135 | | - if (username == null) { |
|---|
| 136 | | - return 0; |
|---|
| 137 | | - } |
|---|
| 138 | | - Integer userRoles = cache.get("roles_" + username, Integer.class); |
|---|
| 139 | | - if (userRoles == null) { |
|---|
| 140 | | - EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 146 | + // Theorically this shouldn't be never null, but just in case... |
|---|
| 147 | + User user = em.find(User.class, username); |
|---|
| 148 | + if (user != null) { |
|---|
| 149 | + userApps = user.getAllAppsIds(); |
|---|
| 150 | + // We store user orgs in cache only for one hour |
|---|
| 151 | + cache.set("apps_" + username, userApps, 3600); |
|---|
| 152 | + } |
|---|
| 153 | + } |
|---|
| 141 | 154 | |
|---|
| 142 | | - User user = em.find(User.class, username); |
|---|
| 143 | | - if (user != null) { |
|---|
| 144 | | - userRoles = 0; |
|---|
| 145 | | - List<Integer> roles = user.getRoles(); |
|---|
| 146 | | - if (roles != null) { |
|---|
| 147 | | - for (Integer rol : roles) { |
|---|
| 148 | | - userRoles += rol; |
|---|
| 149 | | - } |
|---|
| 150 | | - } |
|---|
| 151 | | - // We store user roles in cache only for one hour |
|---|
| 152 | | - cache.set("roles_" + username, userRoles, 3600); |
|---|
| 153 | | - cache.set("orgs_" + username, user.getOrgsIds(), 3600); |
|---|
| 154 | | - } |
|---|
| 155 | | - } |
|---|
| 156 | | - return userRoles == null ? 0 : userRoles.intValue(); |
|---|
| 157 | | - } |
|---|
| 155 | + return userApps; |
|---|
| 156 | + } |
|---|
| 158 | 157 | |
|---|
| 159 | | - // @Override |
|---|
| 160 | | - public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker method) throws Failure, WebApplicationException { |
|---|
| 161 | | - return null; |
|---|
| 162 | | - } |
|---|
| 158 | + private int getUserRoles(String username) { |
|---|
| 159 | + if (username == null) { |
|---|
| 160 | + return 0; |
|---|
| 161 | + } |
|---|
| 162 | + Integer userRoles = cache.get("roles_" + username, Integer.class); |
|---|
| 163 | + if (userRoles == null) { |
|---|
| 164 | + EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 163 | 165 | |
|---|
| 164 | | - @Override |
|---|
| 165 | | - public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException { |
|---|
| 166 | | - context.proceed(); |
|---|
| 167 | | - EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 168 | | - try { |
|---|
| 169 | | - if (em != null && em.getTransaction().isActive()) { |
|---|
| 170 | | - if (servletResponse.getStatus() == Status.OK.getStatusCode()) { |
|---|
| 171 | | - em.getTransaction().commit(); |
|---|
| 172 | | - LOG.debug("COMMIT"); |
|---|
| 173 | | - } else { |
|---|
| 174 | | - // This code is never executed if there is an error the |
|---|
| 175 | | - // filter chain is broken |
|---|
| 176 | | - em.getTransaction().rollback(); |
|---|
| 177 | | - LOG.debug("ROLLBACK"); |
|---|
| 178 | | - } |
|---|
| 179 | | - } |
|---|
| 180 | | - } finally { |
|---|
| 181 | | - if (em.isOpen()) { |
|---|
| 182 | | - LOG.debug("CLOSING EM: {}, trans: {}", em, em.isJoinedToTransaction()); |
|---|
| 183 | | - try { |
|---|
| 184 | | - em.close(); |
|---|
| 185 | | - } catch (Exception ex) { |
|---|
| 186 | | - ex.printStackTrace(); |
|---|
| 187 | | - LOG.error("Error closing EM: {}, {}", em, ex); |
|---|
| 188 | | - } |
|---|
| 189 | | - } |
|---|
| 190 | | - } |
|---|
| 191 | | - } |
|---|
| 166 | + User user = em.find(User.class, username); |
|---|
| 167 | + if (user != null) { |
|---|
| 168 | + userRoles = 0; |
|---|
| 169 | + List<Integer> roles = user.getRoles(); |
|---|
| 170 | + if (roles != null) { |
|---|
| 171 | + for (Integer rol : roles) { |
|---|
| 172 | + userRoles += rol; |
|---|
| 173 | + } |
|---|
| 174 | + } |
|---|
| 175 | + // We store user roles in cache only for one hour |
|---|
| 176 | + cache.set("roles_" + username, userRoles, 3600); |
|---|
| 177 | + cache.set("orgs_" + username, user.getOrgsIds(), 3600); |
|---|
| 178 | + } |
|---|
| 179 | + } |
|---|
| 180 | + return userRoles == null ? 0 : userRoles.intValue(); |
|---|
| 181 | + } |
|---|
| 182 | + |
|---|
| 183 | + // @Override |
|---|
| 184 | + public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker method) throws Failure, WebApplicationException { |
|---|
| 185 | + return null; |
|---|
| 186 | + } |
|---|
| 187 | + |
|---|
| 188 | + @Override |
|---|
| 189 | + public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException { |
|---|
| 190 | + context.proceed(); |
|---|
| 191 | + EntityManager em = ResteasyProviderFactory.getContextData(EntityManager.class); |
|---|
| 192 | + try { |
|---|
| 193 | + if (em != null && em.getTransaction().isActive()) { |
|---|
| 194 | + if (servletResponse.getStatus() == Status.OK.getStatusCode()) { |
|---|
| 195 | + em.getTransaction().commit(); |
|---|
| 196 | + LOG.debug("COMMIT"); |
|---|
| 197 | + } else { |
|---|
| 198 | + // This code is never executed if there is an error the |
|---|
| 199 | + // filter chain is broken |
|---|
| 200 | + em.getTransaction().rollback(); |
|---|
| 201 | + LOG.debug("ROLLBACK"); |
|---|
| 202 | + } |
|---|
| 203 | + } |
|---|
| 204 | + } finally { |
|---|
| 205 | + if (em.isOpen()) { |
|---|
| 206 | + LOG.debug("CLOSING EM: {}, trans: {}", em, em.isJoinedToTransaction()); |
|---|
| 207 | + try { |
|---|
| 208 | + em.close(); |
|---|
| 209 | + } catch (Exception ex) { |
|---|
| 210 | + ex.printStackTrace(); |
|---|
| 211 | + LOG.error("Error closing EM: {}, {}", em, ex); |
|---|
| 212 | + } |
|---|
| 213 | + } |
|---|
| 214 | + } |
|---|
| 215 | + } |
|---|
| 192 | 216 | |
|---|
| 193 | 217 | } |
|---|
| .. | .. |
|---|
| 11 | 11 | |
|---|
| 12 | 12 | public class BasicSecurityContext implements SecurityContext { |
|---|
| 13 | 13 | |
|---|
| 14 | | - final public static String ROL_ADVANCE = "advance"; |
|---|
| 15 | | - final public static String ROL_ADMIN = "admin"; |
|---|
| 14 | + final public static String ROL_ADVANCE = "advance"; |
|---|
| 15 | + final public static String ROL_ADMIN = "admin"; |
|---|
| 16 | + final public static String ROL_BASIC = "basic"; |
|---|
| 16 | 17 | |
|---|
| 17 | | - final static Map<String, Integer> ROLES = Utils.<String, Integer> createMap(ROL_ADVANCE, User.Rol.ADVANCE, ROL_ADMIN, User.Rol.ADMIN); |
|---|
| 18 | + final static Map<String, Integer> ROLES = Utils.<String, Integer> createMap(ROL_BASIC, User.Rol.BASIC, ROL_ADVANCE, User.Rol.ADVANCE, ROL_ADMIN, User.Rol.ADMIN); |
|---|
| 18 | 19 | |
|---|
| 19 | | - Principal user = null; |
|---|
| 20 | | - int roles = 0; |
|---|
| 21 | | - boolean secure = false; |
|---|
| 22 | | - Set<Integer> organizationsIds = null; |
|---|
| 23 | | - double ran = 0; |
|---|
| 20 | + Principal user = null; |
|---|
| 21 | + int roles = 0; |
|---|
| 22 | + boolean secure = false; |
|---|
| 23 | + Set<Integer> organizationsIds = null; |
|---|
| 24 | + Set<Integer> applicationsIds = null; |
|---|
| 25 | + double ran = 0; |
|---|
| 24 | 26 | |
|---|
| 25 | | - public BasicSecurityContext(String username, int roles, boolean secure) { |
|---|
| 26 | | - user = new UserPrincipal(username); |
|---|
| 27 | | - this.roles = roles; |
|---|
| 28 | | - this.secure = secure; |
|---|
| 29 | | - ran = Math.random(); |
|---|
| 30 | | - } |
|---|
| 27 | + public BasicSecurityContext(String username, int roles, boolean secure) { |
|---|
| 28 | + user = new UserPrincipal(username); |
|---|
| 29 | + this.roles = roles; |
|---|
| 30 | + this.secure = secure; |
|---|
| 31 | + ran = Math.random(); |
|---|
| 32 | + } |
|---|
| 31 | 33 | |
|---|
| 32 | | - @Override |
|---|
| 33 | | - public Principal getUserPrincipal() { |
|---|
| 34 | | - return user; |
|---|
| 35 | | - } |
|---|
| 34 | + @Override |
|---|
| 35 | + public Principal getUserPrincipal() { |
|---|
| 36 | + return user; |
|---|
| 37 | + } |
|---|
| 36 | 38 | |
|---|
| 37 | | - @Override |
|---|
| 38 | | - public boolean isUserInRole(String role) { |
|---|
| 39 | | - Integer introle = ROLES.get(role); |
|---|
| 40 | | - return introle != null && (introle & roles) != 0; |
|---|
| 41 | | - } |
|---|
| 39 | + @Override |
|---|
| 40 | + public boolean isUserInRole(String role) { |
|---|
| 41 | + Integer introle = ROLES.get(role); |
|---|
| 42 | + return introle != null && (introle & roles) != 0; |
|---|
| 43 | + } |
|---|
| 42 | 44 | |
|---|
| 43 | | - @Override |
|---|
| 44 | | - public boolean isSecure() { |
|---|
| 45 | | - return secure; |
|---|
| 46 | | - } |
|---|
| 45 | + @Override |
|---|
| 46 | + public boolean isSecure() { |
|---|
| 47 | + return secure; |
|---|
| 48 | + } |
|---|
| 47 | 49 | |
|---|
| 48 | | - @Override |
|---|
| 49 | | - public String getAuthenticationScheme() { |
|---|
| 50 | | - return null; |
|---|
| 51 | | - } |
|---|
| 50 | + @Override |
|---|
| 51 | + public String getAuthenticationScheme() { |
|---|
| 52 | + return null; |
|---|
| 53 | + } |
|---|
| 52 | 54 | |
|---|
| 53 | | - @Override |
|---|
| 54 | | - public String toString() { |
|---|
| 55 | + @Override |
|---|
| 56 | + public String toString() { |
|---|
| 55 | 57 | |
|---|
| 56 | | - return String.format("SecurityContextWrapper(%f) %s", ran, user); |
|---|
| 57 | | - } |
|---|
| 58 | + return String.format("SecurityContextWrapper(%f) %s", ran, user); |
|---|
| 59 | + } |
|---|
| 58 | 60 | |
|---|
| 59 | | - public void setOrganizationsIds(Set<Integer> orgs) { |
|---|
| 60 | | - this.organizationsIds = orgs; |
|---|
| 61 | | - } |
|---|
| 61 | + public void setOrganizationsIds(Set<Integer> orgs) { |
|---|
| 62 | + this.organizationsIds = orgs; |
|---|
| 63 | + } |
|---|
| 62 | 64 | |
|---|
| 63 | | - public Set<Integer> getOrganizationsIds() { |
|---|
| 64 | | - return this.organizationsIds; |
|---|
| 65 | | - } |
|---|
| 65 | + public Set<Integer> getOrganizationsIds() { |
|---|
| 66 | + return this.organizationsIds; |
|---|
| 67 | + } |
|---|
| 66 | 68 | |
|---|
| 67 | | - private class UserPrincipal implements Principal { |
|---|
| 69 | + public Set<Integer> getApplicationsIds() { |
|---|
| 70 | + return applicationsIds; |
|---|
| 71 | + } |
|---|
| 68 | 72 | |
|---|
| 69 | | - final String name; |
|---|
| 73 | + public void setApplicationsIds(Set<Integer> applicationsIds) { |
|---|
| 74 | + this.applicationsIds = applicationsIds; |
|---|
| 75 | + } |
|---|
| 70 | 76 | |
|---|
| 71 | | - public UserPrincipal(String name) { |
|---|
| 72 | | - this.name = name; |
|---|
| 73 | | - } |
|---|
| 77 | + private class UserPrincipal implements Principal { |
|---|
| 74 | 78 | |
|---|
| 75 | | - @Override |
|---|
| 76 | | - public String getName() { |
|---|
| 77 | | - return this.name; |
|---|
| 78 | | - } |
|---|
| 79 | + final String name; |
|---|
| 79 | 80 | |
|---|
| 80 | | - @Override |
|---|
| 81 | | - public String toString() { |
|---|
| 82 | | - return String.format("[%s]", name); |
|---|
| 83 | | - } |
|---|
| 81 | + public UserPrincipal(String name) { |
|---|
| 82 | + this.name = name; |
|---|
| 83 | + } |
|---|
| 84 | 84 | |
|---|
| 85 | | - } |
|---|
| 85 | + @Override |
|---|
| 86 | + public String getName() { |
|---|
| 87 | + return this.name; |
|---|
| 88 | + } |
|---|
| 86 | 89 | |
|---|
| 87 | | - public boolean isOrgAccesible(Integer orgid) { |
|---|
| 88 | | - if (organizationsIds == null || orgid == null) { |
|---|
| 89 | | - return false; |
|---|
| 90 | | - } |
|---|
| 91 | | - return organizationsIds.contains(orgid); |
|---|
| 92 | | - } |
|---|
| 90 | + @Override |
|---|
| 91 | + public String toString() { |
|---|
| 92 | + return String.format("[%s]", name); |
|---|
| 93 | + } |
|---|
| 94 | + |
|---|
| 95 | + } |
|---|
| 96 | + |
|---|
| 97 | + public boolean isOrgAccesible(Integer orgid) { |
|---|
| 98 | + if (organizationsIds == null || orgid == null) { |
|---|
| 99 | + return false; |
|---|
| 100 | + } |
|---|
| 101 | + return organizationsIds.contains(orgid); |
|---|
| 102 | + } |
|---|
| 103 | + |
|---|
| 104 | + public boolean isAppAccesible(Integer appid) { |
|---|
| 105 | + if (applicationsIds == null || appid == null) { |
|---|
| 106 | + return false; |
|---|
| 107 | + } |
|---|
| 108 | + return applicationsIds.contains(appid); |
|---|
| 109 | + } |
|---|
| 110 | + |
|---|
| 93 | 111 | } |
|---|
| .. | .. |
|---|
| 90 | 90 | LOG.info("Getting all packs for user: " + bsc.getUserPrincipal()); |
|---|
| 91 | 91 | q = em.createNamedQuery("list-packs", Pack.class); |
|---|
| 92 | 92 | } else { |
|---|
| 93 | | - if (bsc.getOrganizationsIds() == null) { |
|---|
| 93 | + if (bsc.getOrganizationsIds() == null || bsc.getOrganizationsIds().isEmpty() || // |
|---|
| 94 | + bsc.getApplicationsIds() == null || bsc.getApplicationsIds().isEmpty()) { |
|---|
| 94 | 95 | return Response.ok().build(); |
|---|
| 95 | 96 | } |
|---|
| 96 | | - q = em.createNamedQuery("list-packs-by-orgs", Pack.class); |
|---|
| 97 | | - q.setParameter("list_ids", bsc.getOrganizationsIds()); |
|---|
| 97 | + q = em.createNamedQuery("list-packs-by-orgs-apps", Pack.class); |
|---|
| 98 | + q.setParameter("list_ids_org", bsc.getOrganizationsIds()); |
|---|
| 99 | + q.setParameter("list_ids_app", bsc.getApplicationsIds()); |
|---|
| 100 | + LOG.info("Getting packs from orgs: {} and apps: {}", bsc.getOrganizationsIds(), bsc.getApplicationsIds()); |
|---|
| 98 | 101 | } |
|---|
| 99 | 102 | |
|---|
| 100 | 103 | List<Pack> list = q.getResultList(); |
|---|
| .. | .. |
|---|
| 34 | 34 | import net.curisit.integrity.commons.Utils; |
|---|
| 35 | 35 | import net.curisit.securis.DefaultExceptionHandler; |
|---|
| 36 | 36 | import net.curisit.securis.SeCurisException; |
|---|
| 37 | +import net.curisit.securis.db.Application; |
|---|
| 37 | 38 | import net.curisit.securis.db.Organization; |
|---|
| 38 | 39 | import net.curisit.securis.db.User; |
|---|
| 39 | 40 | import net.curisit.securis.ioc.EnsureTransaction; |
|---|
| .. | .. |
|---|
| 131 | 132 | } |
|---|
| 132 | 133 | |
|---|
| 133 | 134 | try { |
|---|
| 134 | | - this.setUserOrg(user, user.getOrgsIds(), em); |
|---|
| 135 | + this.setUserOrgs(user, user.getOrgsIds(), em); |
|---|
| 136 | + } catch (SeCurisException e) { |
|---|
| 137 | + return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, e.getMessage()).build(); |
|---|
| 138 | + } |
|---|
| 139 | + try { |
|---|
| 140 | + this.setUserApps(user, user.getAppsIds(), em); |
|---|
| 135 | 141 | } catch (SeCurisException e) { |
|---|
| 136 | 142 | return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, e.getMessage()).build(); |
|---|
| 137 | 143 | } |
|---|
| .. | .. |
|---|
| 149 | 155 | return Response.ok(user).build(); |
|---|
| 150 | 156 | } |
|---|
| 151 | 157 | |
|---|
| 152 | | - private void setUserOrg(User user, Set<Integer> orgsIds, EntityManager em) throws SeCurisException { |
|---|
| 158 | + private void setUserOrgs(User user, Set<Integer> orgsIds, EntityManager em) throws SeCurisException { |
|---|
| 153 | 159 | Set<Organization> orgs = null; |
|---|
| 154 | 160 | if (orgsIds != null && !orgsIds.isEmpty()) { |
|---|
| 155 | 161 | orgs = new HashSet<>(); |
|---|
| .. | .. |
|---|
| 165 | 171 | |
|---|
| 166 | 172 | user.setOrganizations(orgs); |
|---|
| 167 | 173 | |
|---|
| 174 | + } |
|---|
| 175 | + |
|---|
| 176 | + private void setUserApps(User user, Set<Integer> appsIds, EntityManager em) throws SeCurisException { |
|---|
| 177 | + Set<Application> apps = null; |
|---|
| 178 | + if (appsIds != null && !appsIds.isEmpty()) { |
|---|
| 179 | + apps = new HashSet<>(); |
|---|
| 180 | + for (Integer appId : appsIds) { |
|---|
| 181 | + Application o = em.find(Application.class, appId); |
|---|
| 182 | + if (o == null) { |
|---|
| 183 | + LOG.error("User application with id {} not found in DB", appId); |
|---|
| 184 | + throw new SeCurisException("User's application not found with ID: " + appId); |
|---|
| 185 | + } |
|---|
| 186 | + apps.add(o); |
|---|
| 187 | + } |
|---|
| 188 | + } |
|---|
| 189 | + |
|---|
| 190 | + user.setApplications(apps); |
|---|
| 168 | 191 | } |
|---|
| 169 | 192 | |
|---|
| 170 | 193 | @PUT |
|---|
| .. | .. |
|---|
| 185 | 208 | } |
|---|
| 186 | 209 | |
|---|
| 187 | 210 | try { |
|---|
| 188 | | - this.setUserOrg(currentUser, user.getOrgsIds(), em); |
|---|
| 211 | + this.setUserOrgs(currentUser, user.getOrgsIds(), em); |
|---|
| 212 | + } catch (SeCurisException e) { |
|---|
| 213 | + return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, e.getMessage()).build(); |
|---|
| 214 | + } |
|---|
| 215 | + try { |
|---|
| 216 | + this.setUserApps(currentUser, user.getAppsIds(), em); |
|---|
| 189 | 217 | } catch (SeCurisException e) { |
|---|
| 190 | 218 | return Response.status(Status.NOT_FOUND).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, e.getMessage()).build(); |
|---|
| 191 | 219 | } |
|---|
| .. | .. |
|---|
| 199 | 227 | } else { |
|---|
| 200 | 228 | // Password has not been modified |
|---|
| 201 | 229 | // return |
|---|
| 202 | | - // Response.status(DefaultExceptionHandler.DEFAULT_APP_ERROR_STATUS_CODE).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, |
|---|
| 203 | | - // "User password is mandatory").build(); |
|---|
| 204 | 230 | } |
|---|
| 205 | 231 | |
|---|
| 206 | 232 | currentUser.setLastLogin(user.getLastLogin()); |
|---|
| .. | .. |
|---|
| 73 | 73 | username VARCHAR(45) NOT NULL, |
|---|
| 74 | 74 | organization_id INT NOT NULL, |
|---|
| 75 | 75 | PRIMARY KEY (username, organization_id)); |
|---|
| 76 | + |
|---|
| 77 | +drop table IF EXISTS user_application; |
|---|
| 78 | +CREATE TABLE IF NOT EXISTS user_application ( |
|---|
| 79 | + username VARCHAR(45) NOT NULL, |
|---|
| 80 | + application_id INT NOT NULL, |
|---|
| 81 | + PRIMARY KEY (username, application_id)); |
|---|
| 82 | + |
|---|
| 76 | 83 | |
|---|
| 77 | 84 | drop table IF EXISTS pack; |
|---|
| 78 | 85 | CREATE TABLE IF NOT EXISTS pack ( |
|---|
| .. | .. |
|---|
| 28 | 28 | |
|---|
| 29 | 29 | <!-- Load the Covalent/Material prebuilt theme --> |
|---|
| 30 | 30 | <link href="node_modules/@covalent/core/theming/prebuilt/blue-orange.css" rel="stylesheet"> |
|---|
| 31 | + |
|---|
| 31 | 32 | <link href="node_modules/ng2-toastr/bundles/ng2-toastr.min.css" rel="stylesheet" /> |
|---|
| 32 | 33 | <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> |
|---|
| 33 | 34 | </head> |
|---|
| .. | .. |
|---|
| 1 | 1 | { |
|---|
| 2 | 2 | "name": "securis", |
|---|
| 3 | 3 | "version": "2.0.0", |
|---|
| 4 | | - "description": "QuickStart package.json from the documentation, supplemented with testing support", |
|---|
| 4 | + "description": "SeCuris front-end application based on Angular4 and Materail design", |
|---|
| 5 | 5 | "scripts": { |
|---|
| 6 | 6 | "build": "tsc -p src/", |
|---|
| 7 | 7 | "build:watch": "tsc -p src/ -w", |
|---|
| .. | .. |
|---|
| 24 | 24 | "author": "", |
|---|
| 25 | 25 | "license": "MIT", |
|---|
| 26 | 26 | "dependencies": { |
|---|
| 27 | | - "@angular/common": "^2.4.9", |
|---|
| 28 | | - "@angular/compiler": "~2.4.9", |
|---|
| 29 | | - "@angular/core": "~2.4.9", |
|---|
| 30 | | - "@angular/forms": "~2.4.9", |
|---|
| 31 | | - "@angular/http": "~2.4.9", |
|---|
| 32 | | - "@angular/material": "^2.0.0-beta.2", |
|---|
| 33 | | - "@angular/platform-browser": "~2.4.9", |
|---|
| 34 | | - "@angular/platform-browser-dynamic": "~2.4.9", |
|---|
| 35 | | - "@angular/router": "^3.4.9", |
|---|
| 36 | | - "@covalent/core": "^1.0.0-beta.2", |
|---|
| 37 | | - "@covalent/dynamic-forms": "^1.0.0-beta.2", |
|---|
| 38 | | - "@covalent/http": "^1.0.0-beta.2", |
|---|
| 27 | + "@angular/common": "^4.0.1", |
|---|
| 28 | + "@angular/compiler": "~4.0.1", |
|---|
| 29 | + "@angular/core": "~4.0.1", |
|---|
| 30 | + "@angular/forms": "~4.0.1", |
|---|
| 31 | + "@angular/http": "~4.0.1", |
|---|
| 32 | + "@angular/animations": "~4.0.1", |
|---|
| 33 | + "@angular/material": "^2.0.0-beta.3", |
|---|
| 34 | + "@angular/platform-browser": "~4.0.1", |
|---|
| 35 | + "@angular/platform-browser-dynamic": "~4.0.1", |
|---|
| 36 | + "@angular/router": "^4.0.1", |
|---|
| 37 | + "@covalent/core": "^1.0.0-beta.3", |
|---|
| 38 | + "@covalent/dynamic-forms": "^1.0.0-beta.3", |
|---|
| 39 | + "@covalent/http": "^1.0.0-beta.3", |
|---|
| 39 | 40 | "angular-2-local-storage": "^1.0.1", |
|---|
| 40 | 41 | "angular-in-memory-web-api": "~0.2.4", |
|---|
| 41 | 42 | "core-js": "^2.4.1", |
|---|
| .. | .. |
|---|
| 1 | 1 | alter table pack add column frozen BOOLEAN NOT NULL default false; |
|---|
| 2 | | -alter table license add column metadata_obsolete BOOLEAN NOT NULL default false; |
|---|
| 2 | +alter table license add column metadata_obsolete BOOLEAN NOT NULL default false; |
|---|
| 3 | + |
|---|
| 4 | +drop table IF EXISTS user_application; |
|---|
| 5 | +CREATE TABLE IF NOT EXISTS user_application ( |
|---|
| 6 | + username VARCHAR(45) NOT NULL, |
|---|
| 7 | + application_id INT NOT NULL, |
|---|
| 8 | + PRIMARY KEY (username, application_id)); |
|---|
| 9 | + |
|---|
| 10 | + |
|---|
| .. | .. |
|---|
| 1 | 1 | import { NgModule } from '@angular/core'; |
|---|
| 2 | 2 | import { BrowserModule } from '@angular/platform-browser'; |
|---|
| 3 | +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; |
|---|
| 3 | 4 | import { CommonModule } from '@angular/common'; |
|---|
| 4 | 5 | import { FormsModule } from '@angular/forms'; |
|---|
| 5 | 6 | import {MaterialModule} from '@angular/material'; |
|---|
| .. | .. |
|---|
| 54 | 55 | storageType: 'localStorage' |
|---|
| 55 | 56 | }), |
|---|
| 56 | 57 | BrowserModule, |
|---|
| 58 | + BrowserAnimationsModule, |
|---|
| 57 | 59 | FormsModule, |
|---|
| 58 | 60 | MaterialModule, |
|---|
| 59 | 61 | CovalentCoreModule.forRoot(), |
|---|
| .. | .. |
|---|
| 29 | 29 | }) |
|---|
| 30 | 30 | export class UserFormComponent extends FormBase { |
|---|
| 31 | 31 | allOrganizations: IComboOption[]; |
|---|
| 32 | + allApplications: IComboOption[]; |
|---|
| 32 | 33 | orgNames: string[] = []; |
|---|
| 33 | | - allRoles: any[] = [{"id":1, "code": "advance", "label":"Advance"}, {"id":2, "code": "admin","label":"Admin"}]; |
|---|
| 34 | + appNames: string[] = []; |
|---|
| 35 | + allRoles: any[] = [{"id":4, "code": "basic","label":"Basic"}, {"id":1, "code": "advance", "label":"Advance"}, {"id":2, "code": "admin","label":"Admin"}]; |
|---|
| 34 | 36 | user_orgs: string[] = []; |
|---|
| 37 | + user_apps: string[] = []; |
|---|
| 35 | 38 | user_roles: any = {}; |
|---|
| 36 | 39 | constructor(private http: Http, |
|---|
| 37 | 40 | private users: UsersService, |
|---|
| 41 | + private applications: ApplicationsService, |
|---|
| 38 | 42 | private organizations: OrganizationsService, |
|---|
| 39 | 43 | router: Router, |
|---|
| 40 | 44 | toaster: ToastsManager, |
|---|
| .. | .. |
|---|
| 50 | 54 | this.user_orgs.forEach(orgName => { |
|---|
| 51 | 55 | var selectedOrg = this.allOrganizations.find(org => org.label === orgName); |
|---|
| 52 | 56 | this.data.organizations_ids.push(selectedOrg.id); |
|---|
| 57 | + }); |
|---|
| 58 | + this.user_apps.forEach(appName => { |
|---|
| 59 | + var selectedApp = this.allApplications.find(app => app.label === appName); |
|---|
| 60 | + this.data.applications_ids.push(selectedApp.id); |
|---|
| 53 | 61 | }); |
|---|
| 54 | 62 | this.user_roles.advance && this.data.roles.push(1); |
|---|
| 55 | 63 | this.user_roles.admin && this.data.roles.push(2); |
|---|
| .. | .. |
|---|
| 71 | 79 | }, |
|---|
| 72 | 80 | err => console.error('Error loading organizations') |
|---|
| 73 | 81 | ); |
|---|
| 82 | + this.applications.get() |
|---|
| 83 | + .map(list => list.map((app : any) => <IComboOption>{id: app.id, label: app.name})) |
|---|
| 84 | + .subscribe( |
|---|
| 85 | + data => { |
|---|
| 86 | + this.allApplications = (<IComboOption[]>data).sort((e1, e2) => e1.label.localeCompare(e2.label)); |
|---|
| 87 | + this.appNames = this.allApplications.map(org => org.label); |
|---|
| 88 | + this._loadApps(); |
|---|
| 89 | + }, |
|---|
| 90 | + err => console.error('Error loading organizations') |
|---|
| 91 | + ); |
|---|
| 74 | 92 | } |
|---|
| 75 | 93 | |
|---|
| 76 | 94 | goBack(): void { |
|---|
| .. | .. |
|---|
| 84 | 102 | }); |
|---|
| 85 | 103 | } |
|---|
| 86 | 104 | } |
|---|
| 105 | + _loadApps() { |
|---|
| 106 | + if (this.data && this.data.applications_ids && this.allApplications && this.allApplications.length > 0) { |
|---|
| 107 | + this.data.applications_ids.forEach((appId : number) => { |
|---|
| 108 | + var selectedApp = this.allApplications.find(app => app.id === appId); |
|---|
| 109 | + this.user_apps.push(selectedApp.label); |
|---|
| 110 | + }); |
|---|
| 111 | + } |
|---|
| 112 | + } |
|---|
| 87 | 113 | init() : void { |
|---|
| 88 | 114 | this.loadCombos(); |
|---|
| 89 | 115 | this.user_orgs = []; |
|---|
| .. | .. |
|---|
| 92 | 118 | super.reset(); |
|---|
| 93 | 119 | super.prepareInitialData('username', { |
|---|
| 94 | 120 | organizations_ids: [], |
|---|
| 121 | + applications_ids: [], |
|---|
| 95 | 122 | roles: [] |
|---|
| 96 | 123 | }, (data) => { |
|---|
| 97 | 124 | this._loadOrgs(); |
|---|
| .. | .. |
|---|
| 7 | 7 | <span flex></span> |
|---|
| 8 | 8 | <button md-icon-button (click)="save()"><md-icon>save</md-icon></button> |
|---|
| 9 | 9 | </md-toolbar> |
|---|
| 10 | | - <!-- |
|---|
| 11 | | - username: 'rym', |
|---|
| 12 | | - roles: [ 1 ], |
|---|
| 13 | | - lastLogin: 1488885433000, |
|---|
| 14 | | - modificationTimestamp: 1479898458000, |
|---|
| 15 | | - email: 'rbouchair@curistec.com', |
|---|
| 16 | | - first_name: 'Rym', |
|---|
| 17 | | - last_name: 'Bouchair', |
|---|
| 18 | | - creation_timestamp: 1479898458000, |
|---|
| 19 | | - organizations_ids: [ 1, 2, 5, 6, 7, 8 ] |
|---|
| 20 | | -} |
|---|
| 21 | | - --> |
|---|
| 22 | 10 | <div class="margin" layout-align-gt-xs="center start" layout-fill="" layout-gt-xs="row"> |
|---|
| 23 | 11 | <md-card flex="70"> |
|---|
| 24 | 12 | <md-card-title> |
|---|
| .. | .. |
|---|
| 79 | 67 | <error-checker [fieldName]="$L.get('field.email')" [formField]="form.controls.email"></error-checker> |
|---|
| 80 | 68 | </div> |
|---|
| 81 | 69 | </div> |
|---|
| 82 | | - <div layout="row" layout-fill layout-padding > |
|---|
| 70 | + <div layout="row" layout-fill layout-padding > |
|---|
| 83 | 71 | <td-chips flex [mdTooltip]="$L.get('Organizations that user can access')" [placeholder]="$L.get('Select organizations')" |
|---|
| 84 | 72 | [items]="orgNames" [(ngModel)]="user_orgs" name="user_orgs" requireMatch> |
|---|
| 85 | 73 | </td-chips> |
|---|
| .. | .. |
|---|
| 92 | 80 | </md-checkbox> |
|---|
| 93 | 81 | </div> |
|---|
| 94 | 82 | </div> |
|---|
| 83 | + <div layout="row" layout-fill layout-padding > |
|---|
| 84 | + <td-chips flex [mdTooltip]="$L.get('Applications that user can access')" [placeholder]="$L.get('Select applications')" |
|---|
| 85 | + [items]="appNames" [(ngModel)]="user_apps" name="user_apps" requireMatch> |
|---|
| 86 | + </td-chips> |
|---|
| 87 | + </div> |
|---|
| 95 | 88 | <div layout="row" layout-fill layout-padding *ngIf="!isNew"> |
|---|
| 96 | 89 | <field-readonly [value]="data.lastLogin || '' | timeAgo" label="field.lastLogin" flex></field-readonly> |
|---|
| 97 | 90 | <field-readonly [value]="data.creation_timestamp | date: 'medium'" label="field.creation_timestamp" flex></field-readonly> |
|---|
| .. | .. |
|---|
| 6 | 6 | <span class="push-left-sm" *ngIf="filteredItems < data.length"> |
|---|
| 7 | 7 | <span class="md-body-1">{{filteredItems}} of {{data.length}} applications filtered</span> |
|---|
| 8 | 8 | </span> |
|---|
| 9 | | - <td-search-box #searchBox class="push-right-sm" placeholder="Search here" (searchDebounce)="search($event)" flex> |
|---|
| 9 | + <td-search-box #searchBox class="push-right-sm" [alwaysVisible]="false" [placeholder]="$L.get('Search here')" (searchDebounce)="search($event)" flex> |
|---|
| 10 | 10 | </td-search-box> |
|---|
| 11 | 11 | <button md-mini-fab color="accent" (click)="create()" [mdTooltip]="$L.get('Create a new application')"> |
|---|
| 12 | 12 | <md-icon>add</md-icon> |
|---|
| .. | .. |
|---|
| 4 | 4 | */ |
|---|
| 5 | 5 | (function (global) { |
|---|
| 6 | 6 | |
|---|
| 7 | | - var ANGULAR_LIBS = ['core', 'http', 'common', 'compiler', 'material', 'flex-layout', // |
|---|
| 7 | + var ANGULAR_LIBS = ['core', 'http', 'common', 'compiler', 'material', 'flex-layout', 'animations', // |
|---|
| 8 | 8 | 'router', 'forms', 'platform-browser', 'platform-browser-dynamic', 'common']; |
|---|
| 9 | 9 | var COVALENT_LIBS = ['core', 'http', 'dynamic-forms']; |
|---|
| 10 | 10 | var mapping = { |
|---|
| .. | .. |
|---|
| 12 | 12 | main: 'src/main.js', |
|---|
| 13 | 13 | 'app': 'src/app', |
|---|
| 14 | 14 | 'environments': 'src/environments', |
|---|
| 15 | + '@angular/animations/browser': 'npm:@angular/animations/bundles/animations-browser.umd.js', |
|---|
| 16 | + '@angular/platform-browser/animations': 'npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js', |
|---|
| 15 | 17 | |
|---|
| 16 | 18 | // other libraries |
|---|
| 17 | 19 | 'rxjs': 'npm:rxjs', |
|---|
| .. | .. |
|---|
| 22 | 24 | } |
|---|
| 23 | 25 | |
|---|
| 24 | 26 | ANGULAR_LIBS.forEach(function (libName) { |
|---|
| 25 | | - mapping['@angular/' + libName] = 'npm:@angular/' + libName + '/bundles/' + libName + '.umd.js'; |
|---|
| 27 | + mapping['@angular/' + libName] = 'npm:@angular/' + libName + '/bundles/' + libName + '.umd.js'; |
|---|
| 26 | 28 | }); |
|---|
| 27 | 29 | |
|---|
| 28 | 30 | COVALENT_LIBS.forEach(function (libName) { |
|---|