From bd890c575163e4d87ac24198b9c68a39cf4bbc4d Mon Sep 17 00:00:00 2001 From: sg481n Date: Mon, 28 Aug 2017 12:11:35 -0400 Subject: Update project structure to org.onap.aaf Update project structure of authz module in aaf from com.att to org.onap.aaf and add distribution management and repositories. Issue-id: AAF-21 Change-Id: Ia2486954e99f2bd60f18122ed60d32d5590781e9 Signed-off-by: sg481n --- .../java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java | 596 +++++++++++++++++++++ .../onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java | 147 +++++ .../onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java | 64 +++ .../java/org/onap/aaf/osaaf/defOrg/Identities.java | 144 +++++ 4 files changed, 951 insertions(+) create mode 100644 authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java create mode 100644 authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java create mode 100644 authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java create mode 100644 authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java (limited to 'authz-defOrg/src/main/java/org') diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java new file mode 100644 index 00000000..0352a1ac --- /dev/null +++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java @@ -0,0 +1,596 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * 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. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.osaaf.defOrg; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +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.authz.env.AuthzEnv; +import org.onap.aaf.authz.env.AuthzTrans; +import org.onap.aaf.authz.org.EmailWarnings; +import org.onap.aaf.authz.org.Executor; +import org.onap.aaf.authz.org.Organization; +import org.onap.aaf.authz.org.OrganizationException; +import org.onap.aaf.osaaf.defOrg.Identities.Data; + +public class DefaultOrg implements Organization { + private static final String PROPERTY_IS_REQUIRED = " property is Required"; + private static final String DOMAIN = "osaaf.com"; + private static final String REALM = "com.osaaf"; + private static final String NAME = "Default Organization"; + private static final String NO_PASS = NAME + " does not support Passwords. Use AAF"; + private final String mailHost,mailFromUserId,supportAddress; + private String SUFFIX; + // Possible ID Pattern + private static final String ID_PATTERN = "a-z[a-z0-9]{5-8}@.*"; + + public DefaultOrg(AuthzEnv env) throws OrganizationException { + String s; + mailHost = env.getProperty(s=(REALM + ".mailHost"), null); + if(mailHost==null) { + throw new OrganizationException(s + PROPERTY_IS_REQUIRED); + } + supportAddress = env.getProperty(s=(REALM + ".supportEmail"), null); + if(supportAddress==null) { + throw new OrganizationException(s + PROPERTY_IS_REQUIRED); + } + + String temp = env.getProperty(s=(REALM + ".mailFromUserId"), null); + mailFromUserId = temp==null?supportAddress:temp; + + System.getProperties().setProperty("mail.smtp.host",mailHost); + System.getProperties().setProperty("mail.user", mailFromUserId); + // Get the default Session object. + session = Session.getDefaultInstance(System.getProperties()); + + SUFFIX='.'+getDomain(); + + try { + String defFile; + temp=env.getProperty(defFile = (getClass().getName()+".file")); + File fIdentities=null; + if(temp==null) { + temp = env.getProperty("aaf_data_dir"); + if(temp!=null) { + 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()) { + dir.mkdirs(); + } + fIdentities.createNewFile(); + } + } + } else { + fIdentities = new File(temp); + if(!fIdentities.exists()) { + String dataDir = env.getProperty("aaf_data_dir"); + if(dataDir!=null) { + fIdentities = new File(dataDir,temp); + } + } + } + + if(fIdentities!=null && fIdentities.exists()) { + identities = new Identities(fIdentities); + } else { + throw new OrganizationException(fIdentities.getCanonicalPath() + " does not exist."); + } + } catch (IOException e) { + throw new OrganizationException(e); + } + } + + // Implement your own Delegation System + static final List NULL_DELEGATES = new ArrayList(); + + public Identities identities; + private boolean dryRun; + private Session session; + public enum Types {Employee, Contractor, Application, NotActive}; + private final static Set typeSet; + + static { + typeSet = new HashSet(); + for(Types t : Types.values()) { + typeSet.add(t.name()); + } + } + + private static final EmailWarnings emailWarnings = new DefaultOrgWarnings(); + + @Override + public String getName() { + return NAME; + } + + @Override + public String getRealm() { + return REALM; + } + + @Override + public String getDomain() { + return DOMAIN; + } + + @Override + public DefaultOrgIdentity getIdentity(AuthzTrans trans, String id) throws OrganizationException { + return new DefaultOrgIdentity(trans,id,this); + } + + // Note: Return a null if found; return a String Message explaining why not found. + @Override + public String isValidID(String id) { + Data data; + try { + data = identities.find(id, identities.reuse()); + } catch (IOException e) { + return getName() + " could not lookup " + id + ": " + e.getLocalizedMessage(); + } + return data==null?id + "is not an Identity in " + getName():null; + } + + @Override + public String isValidPassword(String user, String password, String... prev) { + // If you have an Organization user/Password scheme, use here, otherwise, just use AAF + return NO_PASS; + } + + @Override + public Set getIdentityTypes() { + return typeSet; + } + + @Override + public Response notify(AuthzTrans trans, Notify type, String url, String[] identities, String[] ccs, String summary, Boolean urgent) { + String system = trans.getProperty("CASS_ENV", ""); + + ArrayList toList = new ArrayList(); + Identity identity; + if (identities != null) { + for (String user : identities) { + try { + identity = getIdentity(trans, user); + if (identity == null) { + trans.error().log( + "Failure to obtain User " + user + " for " + + getName()); + } else { + toList.add(identity.email()); + } + } catch (Exception e) { + trans.error().log( + e, + "Failure to obtain User " + user + " for " + + getName()); + } + } + } + + if (toList.isEmpty()) { + trans.error().log("No Users listed to email"); + return Response.ERR_NotificationFailure; + } + + ArrayList ccList = new ArrayList(); + + // If we're sending an urgent email, CC the user's supervisor + // + if (urgent) { + trans.info().log("urgent msg for: " + identities[0]); + try { + List supervisors = getApprovers(trans, identities[0]); + for (Identity us : supervisors) { + trans.info().log("supervisor: " + us.email()); + ccList.add(us.email()); + } + } catch (Exception e) { + trans.error().log(e, + "Failed to find supervisor for " + identities[0]); + } + } + + if (ccs != null) { + for (String user : ccs) { + try { + identity = getIdentity(trans, user); + ccList.add(identity.email()); + } catch (Exception e) { + trans.error().log( + e, + "Failure to obtain User " + user + " for " + + getName()); + } + } + } + + if (summary == null) { + summary = ""; + } + + switch (type) { + case Approval: + try { + sendEmail(trans, toList, ccList, + "AAF Approval Notification " + + (system.length() == 0 ? "" : "(ENV: " + + system + ")"), + "AAF is the " + + NAME + + "System for Fine-Grained Authorizations. You are being asked to Approve" + + (system.length() == 0 ? "" : " in the " + + system + " environment") + + " before AAF Actions can be taken.\n\n" + + "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; + } + break; + case PasswordExpiration: + try { + sendEmail(trans, + toList, + ccList, + "AAF Password Expiration Warning " + + (system.length() == 0 ? "" : "(ENV: " + + system + ")"), + "AAF is the " + + NAME + + " System for Authorizations.\n\nOne or more passwords will expire soon or have expired" + + (system.length() == 0 ? "" : " in the " + + system + " environment") + + ".\n\nPasswords expired for more than 30 days without action are subject to deletion.\n\n" + + "Please follow each link to add a New Password with Expiration Date. Either are valid until expiration. " + + "Use this time to change the passwords on your system. If issues, reply to this email.\n\n" + + summary, urgent); + } catch (Exception e) { + trans.error().log(e, "Failure to send Email"); + return Response.ERR_NotificationFailure; + } + break; + + case RoleExpiration: + try { + sendEmail( + trans, + toList, + ccList, + "AAF Role Expiration Warning " + + (system.length() == 0 ? "" : "(ENV: " + + system + ")"), + "AAF is the " + + NAME + + " System for Authorizations. One or more roles will expire soon" + + (system.length() == 0 ? "" : " in the " + + system + " environment") + + ".\n\nRoles expired for more than 30 days are subject to deletion." + + "Please follow this link the GUI Command line, and either 'extend' or 'del' the user in the role.\n" + + "If issues, reply to this email.\n\n\t" + url + + "\n\n" + summary, urgent); + } catch (Exception e) { + trans.error().log(e, "Failure to send Email"); + return Response.ERR_NotificationFailure; + } + break; + default: + return Response.ERR_NotImplemented; + } + return Response.OK; + } + + @Override + public int sendEmail(AuthzTrans trans, List toList, List ccList, String subject, String body, + Boolean urgent) throws OrganizationException { + int status = 1; + + List to = new ArrayList(); + for(String em : toList) { + if(em.indexOf('@')<0) { + to.add(new DefaultOrgIdentity(trans, em, this).email()); + } else { + to.add(em); + } + } + + List cc = new ArrayList(); + if(ccList!=null && !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(supportAddress)) { + ccList.add(supportAddress); + } + + try { + // Create a default MimeMessage object. + MimeMessage message = new MimeMessage(session); + + // Set From: header field of the header. + message.setFrom(new InternetAddress(mailFromUserId)); + + 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(supportAddress)); + + // Set Subject: header field + message.setSubject("[TESTMODE] " + subject); + + if (urgent) { + message.addHeader("X-Priority", "1"); + } + + ArrayList newBody = new ArrayList(); + + 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. + * add others/change as required + */ + @Override + public Date whenToValidate(Notify type, Date lastValidated) { + switch(type) { + case Approval: + case PasswordExpiration: + return null; + default: + GregorianCalendar gc = new GregorianCalendar(); + gc.setTime(lastValidated); + gc.add(GregorianCalendar.MONTH, 6); // 6 month policy + return gc.getTime(); + } + } + + @Override + public GregorianCalendar expiration(GregorianCalendar gc, Expiration exp, String... extra) { + GregorianCalendar rv = gc==null?new GregorianCalendar():(GregorianCalendar)gc.clone(); + switch (exp) { + case ExtendPassword: + // Extending Password give 5 extra days + rv.add(GregorianCalendar.DATE, 5); + break; + case Future: + // Future Requests last 15 days before subject to deletion. + rv.add(GregorianCalendar.DATE, 15); + break; + case Password: + // Passwords expire in 90 days + rv.add(GregorianCalendar.DATE, 90); + break; + case TempPassword: + // Temporary Passwords last for 12 hours. + rv.add(GregorianCalendar.HOUR, 12); + break; + case UserDelegate: + // Delegations expire max in 2 months + rv.add(GregorianCalendar.MONTH, 2); + break; + case UserInRole: + // Roles expire in 6 months + rv.add(GregorianCalendar.MONTH, 6); + break; + default: + // Unless other wise set, 6 months is default + rv.add(GregorianCalendar.MONTH, 6); + break; + } + return rv; + } + + @Override + public EmailWarnings emailWarningPolicy() { + return emailWarnings; + } + + /** + * Assume the Supervisor is the Approver. + */ + @Override + public List getApprovers(AuthzTrans trans, String user) throws OrganizationException { + Identity orgIdentity = getIdentity(trans, user); + List orgIdentitys = new ArrayList(); + if(orgIdentity!=null) { + String supervisorID = orgIdentity.responsibleTo(); + if (supervisorID.indexOf('@') < 0) { + supervisorID += getDomain(); + } + Identity supervisor = getIdentity(trans, supervisorID); + orgIdentitys.add(supervisor); + } + return orgIdentitys; + } + + @Override + public String getApproverType() { + return "supervisor"; + } + + @Override + public int startOfDay() { + // TODO Auto-generated method stub + return 0; + } + + @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. + // + // 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 + // Identity stores, you need to return "false" if they cannot support multiple Passwords like AAF + return true; + } + + @Override + public boolean isValidCred(String id) { + if(id.endsWith(SUFFIX)) { + return true; + } + return id.matches(ID_PATTERN); + } + + @Override + public String validate(AuthzTrans trans, Policy policy, Executor executor, String... vars) throws OrganizationException { + switch(policy) { + case OWNS_MECHID: + case CREATE_MECHID: + if(vars.length>0) { + Identity requestor = getIdentity(trans, trans.user()); + if(requestor!=null) { + Identity mechid = getIdentity(trans, vars[0]); + if(requestor.equals(mechid.owner())) { + return null; + } + } + } + return trans.user() + " is not the Sponsor of MechID " + vars[0]; + + case CREATE_MECHID_BY_PERM_ONLY: + return getName() + " only allows sponsors to create MechIDs"; + + default: + return policy.name() + " is unsupported at " + getName(); + } + } + + @Override + public boolean isTestEnv() { + return false; + } + + @Override + public void setTestMode(boolean dryRun) { + this.dryRun = dryRun; + } + + /** + * Convert the delimiter String into Internet addresses with the default + * delimiter of ";" + * @param strAddress + * @return + */ + private Address[] getAddresses(List 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 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; + } +} diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java new file mode 100644 index 00000000..d9641bec --- /dev/null +++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * 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. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.osaaf.defOrg; + +import java.io.IOException; +import java.util.List; + +import org.onap.aaf.authz.env.AuthzTrans; +import org.onap.aaf.authz.local.AbsData.Reuse; +import org.onap.aaf.authz.org.Organization; +import org.onap.aaf.authz.org.OrganizationException; +import org.onap.aaf.authz.org.Organization.Identity; +import org.onap.aaf.osaaf.defOrg.Identities.Data; + +import org.onap.aaf.cadi.config.Config; + +/** + * Org Users are essential representations of Identities within the Org. Since this is a highly individual + * thing for most Orgs, i.e. some use LDAP, some need feed, some use something else, this object will allow + * the Organization to connect to their own Identity systems... + * + * + */ +public class DefaultOrgIdentity implements Identity { + private final static int TIMEOUT = Integer.parseInt(Config.AAF_CONN_TIMEOUT_DEF); + + private DefaultOrg org; + private Data identity; + private Identity owner; + + public DefaultOrgIdentity(AuthzTrans trans, String key, DefaultOrg dorg) throws OrganizationException { + org = dorg; + identity=null; + try { + org.identities.open(trans, TIMEOUT); + try { + Reuse r = org.identities.reuse(); + identity = org.identities.find(key, r); + if(identity==null) { + identity = Identities.NO_DATA; + } else { + if("a".equals(identity.status)) { + owner = new DefaultOrgIdentity(trans,identity.responsibleTo,org); + } else { + owner = null; + } + } + } finally { + org.identities.close(trans); + } + } catch (IOException e) { + throw new OrganizationException(e); + } + } + + @Override + public boolean equals(Object b) { + if(b instanceof DefaultOrgIdentity) { + return identity.id.equals(((DefaultOrgIdentity)b).identity.id); + } + return false; + } + + @Override + public String id() { + return identity.id; + } + + @Override + public String fullID() { + return identity.id+'@'+org.getDomain(); + } + + @Override + public String type() { + switch(identity.status) { + case "e": return DefaultOrg.Types.Employee.name(); + case "c": return DefaultOrg.Types.Contractor.name(); + case "a": return DefaultOrg.Types.Application.name(); + case "n": return DefaultOrg.Types.NotActive.name(); + default: + return "Unknown"; + } + } + + @Override + public String responsibleTo() { + return identity.responsibleTo; + } + + @Override + public List delegate() { + //NOTE: implement Delegate system, if desired + return DefaultOrg.NULL_DELEGATES; + } + + @Override + public String email() { + return identity.email; + } + + @Override + public String fullName() { + return identity.name; + } + + @Override + public boolean isResponsible() { + return "e".equals(identity.status); // Assume only Employees are responsible for Resources. + } + + @Override + public boolean isFound() { + return identity!=null; + } + + @Override + public Identity owner() throws OrganizationException { + return owner; + } + + @Override + public Organization org() { + return org; + } + +} diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java new file mode 100644 index 00000000..3618379d --- /dev/null +++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * 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. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.osaaf.defOrg; + +import org.onap.aaf.authz.org.EmailWarnings; + +public class DefaultOrgWarnings implements EmailWarnings { + + @Override + public long credEmailInterval() + { + return 604800000L; // 7 days in millis 1000 * 86400 * 7 + } + + @Override + public long roleEmailInterval() + { + return 604800000L; // 7 days in millis 1000 * 86400 * 7 + } + + @Override + public long apprEmailInterval() { + return 259200000L; // 3 days in millis 1000 * 86400 * 3 + } + + @Override + public long credExpirationWarning() + { + return( 2592000000L ); // One month, in milliseconds 1000 * 86400 * 30 in milliseconds + } + + @Override + public long roleExpirationWarning() + { + return( 2592000000L ); // One month, in milliseconds 1000 * 86400 * 30 in milliseconds + } + + @Override + public long emailUrgentWarning() + { + return( 1209600000L ); // Two weeks, in milliseconds 1000 * 86400 * 14 in milliseconds + } + +} diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java new file mode 100644 index 00000000..f7f1319d --- /dev/null +++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * 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. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.osaaf.defOrg; + +import java.io.File; +import java.io.IOException; + +import org.onap.aaf.authz.local.AbsData; +import org.onap.aaf.authz.local.DataFile.Token.Field; + +/* + * Example User Data file, which can be modified for many different kinds of Data Feeds. + * + * Note: This has shown to be extremely effective in AT&T, an acknowledged very large organizations, + * because there is no need to synchronize records. AAF simply receives a Data Feed in Organization + * defined intervals. (You might want to check for validity, such as size, etc), then is copied into + * Data Directory. You will want to do so first creating a "lock" file. Assuming the File name is "users.dat", + * the Lock File is "users.lock". + * + * After the movement of the Datafile into place, it is best to remove the Index File, then remove the lock file. + * + * Note, Any AAF Programs needing this data WILL wait on the Lock file, so you should get fresh Data files + * in a "stage" directory, from WEB, or wherever, and then, after it is correct, do the following as fast as feasible. + * + * a) lock + * b) copy from stage + * c) remove idx + * d) unlock + * + * If the Index File is either non-existent or out of date from the Data File, it will be reindexed, which + * has proven to be a very quick function, even with large numbers of entries. + * + * This Sample Feed is set for a file with delimiter of "|". 512 is maximum expected line length. The "0" is the + * field offset for the "key" to the record, which, for user, should be the unique Organization Identity. + * + */ +public class Identities extends AbsData { + public final static Data NO_DATA = new Data(); + + public Identities(File users) { + super(users,'|',512,0); + } + + /* + * Example Field Layout. note, in this example, Application IDs and People IDs are mixed. You may want to split + * out AppIDs, choose your own status indicators, or whatever you use. + * 0 - unique ID + * 1 - full name + * 2 - first name + * 3 - last name + * 4 - phone + * 5 - official email + * 6 - employment status e=employee, c=contractor, a=application, n=no longer with company + * 7 - responsible to (i.e Supervisor for People, or AppOwner, if it's an App ID) + */ + public static class Data { + public final String id; + public final String name; + public final String fname; + public final String lname; + public final String phone; + public final String email; + public final String status; + public final String responsibleTo; + + private Data(Field f) { + f.reset(); + id=f.next(); + name=f.next(); + fname=f.next(); + lname=f.next(); + phone=f.next(); + email=f.next(); + status=f.next(); + responsibleTo =f.next(); + } + + private Data() { + id = name = fname = lname = + phone = email = status = responsibleTo + = ""; + } + + public String toString() { + return id + '|' + + name + '|' + + lname + '|' + + fname + '|' + + phone + '|' + + email + '|' + + status + '|' + + responsibleTo; + } + + // Here, make up your own Methods which help you easily determine your Organization's structure + // in your Organization Object + public boolean hasStatus(String possible) { + return possible.contains(status); + } + + public boolean isEmployee() { + return "e".equals(status); + } + + public boolean isContractor() { + return "c".equals(status); + } + + public boolean isApplication() { + return "a".equals(status); + } + } + + public Data find(Object key,Reuse r) throws IOException { + r.getFieldData().reset(); + // These are new, to allow for Thread Safety + int rec = ti.find(key,r.getTokenData(),r.getFieldData(),0); + if(rec<0) { + return null; + } + r.getTokenData().pos(rec); + return new Data(r.getFieldData()); + } +} -- cgit 1.2.3-korg