Merge "fix critical sonar"
[aaf/authz.git] / auth / auth-deforg / src / main / java / org / onap / aaf / org / DefaultOrg.java
index 935f99b..f3c7321 100644 (file)
@@ -7,9 +7,9 @@
  * * Licensed under the Apache License, Version 2.0 (the "License");
  * * you may not use this file except in compliance with the License.
  * * You may obtain a copy of the License at
- * * 
+ * *
  *  *      http://www.apache.org/licenses/LICENSE-2.0
- * * 
+ * *
  *  * Unless required by applicable law or agreed to in writing, software
  * * distributed under the License is distributed on an "AS IS" BASIS,
  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -31,14 +31,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.regex.Pattern;
 
-import javax.mail.Address;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.org.EmailWarnings;
 import org.onap.aaf.auth.org.Executor;
@@ -54,13 +46,15 @@ public class DefaultOrg implements Organization {
        final String domain;
        final String atDomain;
        final String realm;
-       
+
        private final String NAME,mailHost,mailFrom;
        private final Set<String> supportedRealms;
 
+
        public DefaultOrg(Env env, String realm) throws OrganizationException {
+
                this.realm = realm;
-               supportedRealms=new HashSet<String>();
+               supportedRealms=new HashSet<>();
                supportedRealms.add(realm);
                domain=FQI.reverseDomain(realm);
                atDomain = '@'+domain;
@@ -75,10 +69,19 @@ public class DefaultOrg implements Organization {
                        throw new OrganizationException(s + PROPERTY_IS_REQUIRED);
                }
                
+               // Note: This code is to avoid including javax.mail into ONAP, because there are security/licence 
+               // exceptions
+               try {
+                       Class.forName("javax.mail.Session"); // ensure package is loaded
+                       @SuppressWarnings("unchecked")
+                       Class<Mailer> minst = (Class<Mailer>)Class.forName("org.onap.aaf.org.JavaxMailer");
+                       mailer = minst.newInstance();
+               } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e1) {
+                       env.warn().log("JavaxMailer not loaded. Mailing disabled");
+               }
+
                System.getProperties().setProperty("mail.smtp.host",mailHost);
                System.getProperties().setProperty("mail.user", mailFrom);
-               // Get the default Session object.
-               session = Session.getDefaultInstance(System.getProperties());
 
                try {
                        String defFile;
@@ -90,6 +93,7 @@ public class DefaultOrg implements Organization {
                                        env.warn().log(defFile, " is not defined. Using default: ",temp+"/identities.dat");
                                        File dir = new File(temp);
                                        fIdentities=new File(dir,"identities.dat");
+
                                        if(!fIdentities.exists()) {
                                                env.warn().log("No",fIdentities.getCanonicalPath(),"exists.  Creating.");
                                                if(!dir.exists()) {
@@ -107,7 +111,7 @@ public class DefaultOrg implements Organization {
                                        }
                                }
                        }
-                       
+
                        if(fIdentities!=null && fIdentities.exists()) {
                                identities = new Identities(fIdentities);
                        } else {
@@ -121,23 +125,23 @@ public class DefaultOrg implements Organization {
                        throw new OrganizationException(e);
                }
        }
-       
+
        // Implement your own Delegation System
-       static final List<String> NULL_DELEGATES = new ArrayList<String>();
+       static final List<String> NULL_DELEGATES = new ArrayList<>();
 
        public Identities identities;
        private boolean dryRun;
-       private Session session;
+       private Mailer mailer;
        public enum Types {Employee, Contractor, Application, NotActive};
        private final static Set<String> typeSet;
-       
+
        static {
-               typeSet = new HashSet<String>();
+               typeSet = new HashSet<>();
                for(Types t : Types.values()) {
                        typeSet.add(t.name());
                }
        }
-       
+
        private static final EmailWarnings emailWarnings = new DefaultOrgWarnings();
 
        @Override
@@ -161,7 +165,7 @@ public class DefaultOrg implements Organization {
                return new DefaultOrgIdentity(trans,at<0?id:id.substring(0, at),this);
        }
 
-       // Note: Return a null if found; return a String Message explaining why not found. 
+       // Note: Return a null if found; return a String Message explaining why not found.
        @Override
        public String isValidID(final AuthzTrans trans, final String id) {
                try {
@@ -185,29 +189,42 @@ public class DefaultOrg implements Organization {
 //                     if(!id.regionMatches(at+1, domain, 0, id.length()-at-1)) {
 //                             return false;
 //                     }
-                       sid = id.substring(0,at); 
+                       sid = id.substring(0,at);
                } else {
                        sid = id;
                }
                // We'll validate that it exists, rather than check patterns.
-               
+
                return isValidID(trans, sid)==null;
                // Check Pattern (if checking existing is too long)
                //              if(id.endsWith(SUFFIX) && ID_PATTERN.matcher(id).matches()) {
                //                      return true;
                //              }
-               //              return false; 
+               //              return false;
        }
 
        private static final String SPEC_CHARS = "!@#$%^*-+?/,:;.";
-       private static final Pattern PASS_PATTERN=Pattern.compile("((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[" + SPEC_CHARS +"]).{6,20})");
+       private static final Pattern PASS_PATTERN=Pattern.compile("(((?=.*[a-z,A-Z])(((?=.*\\d))|(?=.*[" + SPEC_CHARS +"]))).{6,20})");
        /**
+        *  (                           # Start of group
+        *  (?=.*[a-z,A-Z])     #   must contain one character
+        *  
+        *  (?=.*\d)            #   must contain one digit from 0-9 
+        *        OR
+        *  (?=.*[@#$%])        #   must contain one special symbols in the list SPEC_CHARS
+        *  
+        *              .               #     match anything with previous condition checking
+        *          {6,20}      #        length at least 6 characters and maximum of 20
+        *  )                           # End of group
+        *
+        * Another example, more stringent pattern
+        private static final Pattern PASS_PATTERN=Pattern.compile("((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[" + SPEC_CHARS +"]).{6,20})");
         *  Attribution: from mkyong.com
         *  (                           # Start of group
-        *  (?=.*\d)                    #   must contains one digit from 0-9
-        *  (?=.*[a-z])         #   must contains one lowercase characters
-        *  (?=.*[A-Z])         #   must contains one uppercase characters
-        *  (?=.*[@#$%])                #   must contains one special symbols in the list SPEC_CHARS
+        *  (?=.*\d)            #   must contain one digit from 0-9
+        *  (?=.*[a-z])         #   must contain one lowercase characters
+        *  (?=.*[A-Z])         #   must contain one uppercase characters
+        *  (?=.*[@#$%])        #   must contain one special symbols in the list SPEC_CHARS
         *              .               #     match anything with previous condition checking
         *          {6,20}      #        length at least 6 characters and maximum of 20
         *  )                           # End of group
@@ -227,11 +244,11 @@ public class DefaultOrg implements Organization {
        }
 
        private static final String[] rules = new String[] {
-                       "Passwords must contain one digit from 0-9",
-                       "Passwords must contain one lowercase character",
-                       "Passwords must contain one uppercase character",
-                       "Passwords must contain one special symbols in the list \""+ SPEC_CHARS + '"',
-                       "Passwords must be between 6 and 20 chars in length"
+                       "Passwords must contain letters",
+                       "Passwords must contain one of the following:",
+                       "  Number",
+                       "  One special symbols in the list \""+ SPEC_CHARS + '"',
+                       "Passwords must be between 6 and 20 chars in length",
        };
 
        @Override
@@ -248,7 +265,7 @@ public class DefaultOrg implements Organization {
        public Response notify(AuthzTrans trans, Notify type, String url, String[] identities, String[] ccs, String summary, Boolean urgent) {
                String system = trans.getProperty("CASS_ENV", "");
 
-               ArrayList<String> toList = new ArrayList<String>();
+               ArrayList<String> toList = new ArrayList<>();
                Identity identity;
                if (identities != null) {
                        for (String user : identities) {
@@ -275,7 +292,7 @@ public class DefaultOrg implements Organization {
                        return Response.ERR_NotificationFailure;
                }
 
-               ArrayList<String> ccList = new ArrayList<String>();
+               ArrayList<String> ccList = new ArrayList<>();
 
                // If we're sending an urgent email, CC the user's supervisor
                //
@@ -327,6 +344,7 @@ public class DefaultOrg implements Organization {
                                                                + "Please follow this link: \n\n\t" + url
                                                                + "\n\n" + summary, urgent);
                        } catch (Exception e) {
+
                                trans.error().log(e, "Failure to send Email");
                                return Response.ERR_NotificationFailure;
                        }
@@ -383,109 +401,6 @@ public class DefaultOrg implements Organization {
                return Response.OK;
        }
 
-       @Override
-       public int sendEmail(AuthzTrans trans, List<String> toList, List<String> ccList, String subject, String body,
-                       Boolean urgent) throws OrganizationException {
-               int status = 1;
-               
-               List<String> to = new ArrayList<String>();
-               for(String em : toList) {
-                       if(em.indexOf('@')<0) {
-                               to.add(new DefaultOrgIdentity(trans, em, this).email());
-                       } else {
-                               to.add(em);
-                       }
-               }
-               
-               List<String> cc = new ArrayList<String>();
-               if(ccList!=null) {
-                       if(!ccList.isEmpty()) {
-                       
-                               for(String em : ccList) {
-                                       if(em.indexOf('@')<0) {
-                                               cc.add(new DefaultOrgIdentity(trans, em, this).email());
-                                       } else {
-                                               cc.add(em);
-                                       }
-                               }
-                       }
-                       
-                       // for now, I want all emails so we can see what goes out. Remove later
-                       if (!ccList.contains(mailFrom)) {
-                               ccList.add(mailFrom);
-                       }
-               }
-
-               try {
-                       // Create a default MimeMessage object.
-                       MimeMessage message = new MimeMessage(session);
-
-                       // Set From: header field of the header.
-                       message.setFrom(new InternetAddress(mailFrom));
-
-                       if (!dryRun) {
-                               // Set To: header field of the header. This is a required field
-                               // and calling module should make sure that it is not null or
-                               // blank
-                               message.addRecipients(Message.RecipientType.TO,getAddresses(to));
-
-                               // Set CC: header field of the header.
-                               if ((ccList != null) && (ccList.size() > 0)) {
-                                       message.addRecipients(Message.RecipientType.CC,getAddresses(cc));
-                               }
-
-                               // Set Subject: header field
-                               message.setSubject(subject);
-
-                               if (urgent) {
-                                       message.addHeader("X-Priority", "1");
-                               }
-
-                               // Now set the actual message
-                               message.setText(body);
-                       } else {
-                               // override recipients
-                               message.addRecipients(Message.RecipientType.TO,
-                                               InternetAddress.parse(mailFrom));
-
-                               // Set Subject: header field
-                               message.setSubject("[TESTMODE] " + subject);
-
-                               if (urgent) {
-                                       message.addHeader("X-Priority", "1");
-                               }
-
-                               ArrayList<String> newBody = new ArrayList<String>();
-
-                               Address temp[] = getAddresses(to);
-                               String headerString = "TO:\t" + InternetAddress.toString(temp) + "\n";
-
-                               temp = getAddresses(cc);
-                               headerString += "CC:\t" + InternetAddress.toString(temp) + "\n";
-
-                               newBody.add(headerString);
-
-                               newBody.add("Text: \n");
-
-                               newBody.add(body);
-                               String outString = "";
-                               for (String s : newBody) {
-                                       outString += s + "\n";
-                               }
-
-                               message.setText(outString);
-                       }
-                       // Send message
-                       Transport.send(message);
-                       status = 0;
-
-               } catch (MessagingException mex) {
-                       throw new OrganizationException("Exception send email message "
-                                       + mex.getMessage());
-               }
-
-               return status;  
-       }
 
        /**
         * Default Policy is to set to 6 Months for Notification Types.
@@ -507,8 +422,8 @@ public class DefaultOrg implements Organization {
 
        @Override
        public GregorianCalendar expiration(GregorianCalendar gc, Expiration exp, String... extra) {
-        GregorianCalendar now = new GregorianCalendar();
-        GregorianCalendar rv = gc==null?now:(GregorianCalendar)gc.clone();
+               GregorianCalendar now = new GregorianCalendar();
+               GregorianCalendar rv = gc==null?now:(GregorianCalendar)gc.clone();
                switch (exp) {
                        case ExtendPassword:
                                // Extending Password give 5 extra days, max 8 days from now
@@ -566,14 +481,14 @@ public class DefaultOrg implements Organization {
        @Override
        public List<Identity> getApprovers(AuthzTrans trans, String user) throws OrganizationException {
                Identity orgIdentity = getIdentity(trans, user);
-               List<Identity> orgIdentitys = new ArrayList<Identity>();
+               List<Identity> orgIdentitys = new ArrayList<>();
                if(orgIdentity!=null) {
                        Identity supervisor = orgIdentity.responsibleTo();
                        if(supervisor!=null) {
                                orgIdentitys.add(supervisor);
                        }
                }
-               return orgIdentitys;    
+               return orgIdentitys;
        }
 
        @Override
@@ -590,7 +505,7 @@ public class DefaultOrg implements Organization {
        @Override
        public boolean canHaveMultipleCreds(String id) {
                // External entities are likely mono-password... if you change it, it is a global change.
-               // This is great for people, but horrible for Applications.  
+               // This is great for people, but horrible for Applications.
                //
                // AAF's Password can have multiple Passwords, each with their own Expiration Date.
                // For Default Org, we'll assume true for all, but when you add your external
@@ -621,13 +536,13 @@ public class DefaultOrg implements Organization {
                                        }
                                }
                                return null;
-                               
+
                        case CREATE_MECHID_BY_PERM_ONLY:
                                return getName() + " only allows sponsors to create MechIDs";
-                               
+
                        default:
                                return policy.name() + " is unsupported at " + getName();
-               }       
+               }
        }
 
        @Override
@@ -640,37 +555,6 @@ public class DefaultOrg implements Organization {
                this.dryRun = dryRun;
        }
 
-       /**
-        * Convert the delimiter String into Internet addresses with the default
-        * delimiter of ";"
-        * @param strAddress
-        * @return
-        */
-       private Address[] getAddresses(List<String> strAddress) throws OrganizationException {
-               return this.getAddresses(strAddress,";");
-       }
-       /**
-        * Convert the delimiter String into Internet addresses with the 
-        * delimiter of provided
-        * @param strAddress
-        * @param delimiter
-        * @return
-        */
-       private Address[] getAddresses(List<String> strAddresses, String delimiter) throws OrganizationException {
-               Address[] addressArray = new Address[strAddresses.size()];
-               int count = 0;
-               for (String addr : strAddresses)
-               {
-            try{
-               addressArray[count] = new InternetAddress(addr);
-               count++;
-            }catch(Exception e){
-               throw new OrganizationException("Failed to parse the email address "+ addr +": "+e.getMessage());
-            }
-        }
-        return addressArray;
-       }
-
        private String extractRealm(final String r) {
                int at;
                if((at=r.indexOf('@'))>=0) {
@@ -680,12 +564,59 @@ public class DefaultOrg implements Organization {
        }
        @Override
        public boolean supportsRealm(final String r) {
-               return supportedRealms.contains(extractRealm(r)) || r.endsWith(realm);
+               if(r.endsWith(realm)) {
+                       return true;
+               } else {
+                       String erealm = extractRealm(r);
+                       for(String sr : supportedRealms) {
+                               if(erealm.startsWith(sr)) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
        }
 
        @Override
        public synchronized void addSupportedRealm(final String r) {
                supportedRealms.add(extractRealm(r));
        }
-                       
+
+       @Override
+       public int sendEmail(AuthzTrans trans, List<String> toList, List<String> ccList, String subject, String body,
+                       Boolean urgent) throws OrganizationException {
+               if (mailer!=null) {
+                       List<String> to = new ArrayList<>();
+                       for(String em : toList) {
+                               if(em.indexOf('@')<0) {
+                                       to.add(new DefaultOrgIdentity(trans, em, this).email());
+                               } else {
+                                       to.add(em);
+                               }
+                       }
+
+                       List<String> cc = new ArrayList<>();
+                       if(ccList!=null) {
+                               if(!ccList.isEmpty()) {
+
+                                       for(String em : ccList) {
+                                               if(em.indexOf('@')<0) {
+                                                       cc.add(new DefaultOrgIdentity(trans, em, this).email());
+                                               } else {
+                                                       cc.add(em);
+                                               }
+                                       }
+                               }
+
+                               // for now, I want all emails so we can see what goes out. Remove later
+                               if (!ccList.contains(mailFrom)) {
+                                       ccList.add(mailFrom);
+                               }
+                       }
+
+                       return mailer.sendEmail(trans,dryRun,mailFrom,to,cc,subject,body,urgent);
+               } else {
+                       return 0;
+               }
+       }
 }