<html> <head> <script> /* TODO: - Incorporate the courses (after adding more); - randomly add a second non-duplticating affliate */ // https://stackoverflow.com/a/424445 function RNG(seed) { // LCG using GCC's constants this.m = 0x80000000; // 2**31; this.a = 1103515245; this.c = 12345; this.state = seed ? seed : Math.floor(Math.random() * (this.m - 1)); } RNG.prototype.nextInt = function() { this.state = (this.a * this.state + this.c) % this.m; return this.state; } RNG.prototype.nextFloat = function() { // returns in range [0,1] return this.nextInt() / (this.m - 1); } RNG.prototype.nextRange = function(start, end) { // returns in range [start, end): including start, excluding end // can't modulu nextInt because of weak randomness in lower bits var rangeSize = end - start; var randomUnder1 = this.nextInt() / this.m; return start + Math.floor(randomUnder1 * rangeSize); } RNG.prototype.choice = function(array) { return array[this.nextRange(0, array.length)]; } var surnames = ["Gasper", "Smith", "Anderson", "Roberts", "Davis", "Brown", "Langenberg", "Vales", "Grady", "Doe", "Morrison", "Walters", "Johnson", "Williams", "Peterson", "Martinez", "Thompson", "White", "Lee", "Clark", "Lewis", "Lopez", "Gonazles", "Scott", "Henderson", "Butler", "Price", "Nielson" ]; var givenNames = ["John", "Michael", "Jennifer", "Nancy", "Bill", "William", "Kiersten", "Marie", "Lori", "Mark", "Eric", "David", "Ann", "Donna", "Paul", "Thomas", "Robert", "David", "Jim", "James", "Blake", "Sarah", "Karoline", "Kim", "Erik", "Greg", "Karl", "Colin", "Jo", "Betty", "Lisa", "Heather", "Mary", "Stephanie", "Christina", "Christopher", "Jeremy", "Nancy", "Amber", "Adian", "Perry", "Steve", "Andrew", "Megan", "Anna", "Claire", "Maddie", "Madison", "Debbie", "Lexi", "Olivia", "Emma", "Ava", "Sophia", "Isabella", "Mia" ]; var departments = ["Computer Science", "Engineering", "Business", "Accounting", "Law", "Physical Education", "Language Arts", "Financial Aid", "Information Technology", "Advising", "Purchasing", "Accounts Payable" ]; var affiliations = ["student", "staff", "faculty", "alum", "community"]; var courses = ["ACCT101", "ACCT201", "MATH100", "MATH101", "CS251", "CS252", "ENGL101", "ENGL102", "ENGL201", "HIST101", "HIST102", "SCI123", "SCI123", "SCI404" ]; var rng; function generateData() { var people = []; var seed = parseInt(document.getElementById('seed').value); rng = new RNG(seed); var personCount = parseInt(document.getElementById('count').value) - 1; var peopleOu = document.getElementById('people_ou').value; for (i = 0; i <= personCount; i++) { surname = surnames[rng.nextRange(0, surnames.length)]; givenName = givenNames[rng.nextRange(0, givenNames.length)]; idNumber = "8" + (i + 1).toString().padStart(7, "0"); uid = givenName[0] + surname + i; var person = { uid: uid.toLowerCase(), surname: surname, givenName: givenName, idNumber: idNumber, }; people.push(person); } //Add additional randomized characteristics sets here; //keep the ordering the same to maintain deterministic capabilities between runs //Assign departments for (index = 0; index < people.length; ++index) { people[index]["department"] = departments[rng.nextRange(0, departments.length)]; } //Assign affiliations for (index = 0; index < people.length; ++index) { people[index]["affiliations"] = selectUnduplicated(affiliations, 2); } //Assign titles/primary affiliations for (index = 0; index < people.length; ++index) { people[index]["title"] = rankAffiliations(people[index].affiliations); } //Create Course Enrollments for (index = 0; index < people.length; ++index) { people[index]["courses"] = []; if (people[index]["affiliations"].indexOf("student") > -1 || people[index]["affiliations"].indexOf("faculty") > -1) { people[index]["courses"] = selectUnduplicated(courses, 4); } } //Create vpn_users for (index = 0; index < people.length; ++index) { people[index].vpn_user = people[index].affiliations.indexOf('staff') >= 0 || people[index].affiliations.indexOf('faculty') >= 0 ? (rng.nextFloat() > 0.1): //grab most faculty and staff rng.nextFloat() > 0.9; // and only a few others } //Create vpn users ldap group makeQuestionableVpnUsersLists(people); //Create Athletics users makeAthleticsUsersLists(people); //Create lists of non-faculty (staff) banner users makeNonFacultyBannerUsersLists(people); //Create lists of visiting scholars makeVisitingScholarsLists(people); console.log(people); //Generate Output var ldif = ""; for (j = 0; j < people.length; j++) { ldif += formatPersonLdif(people[j], peopleOu); } ldif += formatVpnUsersGroupLdif(people, peopleOu); ldif += formatCommunityGroupLdif(people, peopleOu); document.getElementById('ldif').value = ldif; var sql = ""; sql += sqlHeader(); for (k = 0; k < people.length; k++) { sql += formatSqlSubjects(people[k]); sql += formatSqlCourses(people[k]); } document.getElementById('sql').value = sql; } function formatPersonLdif(person, ou) { var output = "dn: uid=<uid>," + ou + "\n" + "objectClass: organizationalPerson\n" + "objectClass: person\n" + "objectClass: top\n" + "objectClass: inetOrgPerson\n" + "objectClass: eduPerson\n" + "surname: <surname>\n" + "givenName: <givenName>\n" + "cn: <givenName> <surname>\n" + "uid: <uid>\n" + "title: <title>\n" + "employeeNumber: <idNumber>\n" + "mail: <uid>@example.edu\n" + "businessCategory:<department>\n" + "userPassword: password\n"; output = output.replace(/<uid>/g, person.uid); output = output.replace(/<surname>/g, person.surname); output = output.replace(/<givenName>/g, person.givenName); output = output.replace(/<department>/g, person.department); output = output.replace(/<title>/g, person.title); output = output.replace(/<idNumber>/g, person.idNumber); for (i = 0; i < person.affiliations.length; i++) { output += "eduPersonAffiliation: " + person.affiliations[i] + "\n"; } return output + "\n"; } function formatVpnUsersGroupLdif(people, ou) { var vpnOutput = "dn: cn=vpn_users,ou=groups,dc=internet2,dc=edu\n" + "objectClass: groupOfNames\n" + "objectClass: top\n" + "cn: vpn_users\n" for (j = 0; j < people.length; j++) { if (people[j].vpn_user == 1) { vpnOutput = vpnOutput + "member: uid=" + people[j].uid + ',' + ou + "\n" } } return vpnOutput + "\n"; } function formatCommunityGroupLdif(people, ou) { var vpnOutput = "dn: cn=community_members,ou=groups,dc=internet2,dc=edu\n" + "objectClass: groupOfNames\n" + "objectClass: top\n" + "cn: community_members\n" for (j = 0; j < people.length; j++) { if (people[j].affiliations.indexOf('community') >= 0 ) { vpnOutput = vpnOutput + "member: uid=" + people[j].uid + ',' + ou + "\n" } } return vpnOutput + "\n"; } function sqlHeader() { return "CREATE TABLE SIS_COURSES (\n" + " termId varchar(255) NOT NULL,\n" + " courseId varchar(255) NOT NULL,\n" + " studentId varchar(255) NOT NULL,\n" + " PRIMARY KEY (termId, courseId, studentId)\n" + ");\n\n" + "CREATE TABLE HR_PEOPLE (\n" + " id varchar(255) NOT NULL,\n" + " surname varchar(255) default NULL,\n" + " givenName varchar(255) default NULL,\n" + " PRIMARY KEY (id)\n" + ");\n\n" + "CREATE TABLE HR_PEOPLE_ROLES (\n" + " id varchar(255) NOT NULL,\n" + " role varchar(255) NOT NULL,\n" + " PRIMARY KEY (id, role)\n" + ");\n\n"; } function formatSqlCourses(person) { var template = "INSERT INTO SIS_COURSES (termId, courseId, studentId) " + "VALUES ('201810','<courseId>','<id>');\n"; var output = ""; for (i = 0; i < person.courses.length; i++) { temp = template.replace(/<id>/g, person.idNumber); temp = temp.replace(/<courseId>/g, person.courses[i]); output += temp; } return output; } function formatSqlSubjects(person) { var template = "INSERT INTO HR_PEOPLE(id, surname, givenName) " + "VALUES ('<id>','<surname>','<givenName>');\n"; var output = ""; temp = template.replace(/<id>/g, person.idNumber); temp = temp.replace(/<surname>/g, person.surname); temp = temp.replace(/<givenName>/g, person.givenName); output += temp; var template = "INSERT INTO HR_PEOPLE_ROLES(id, role) " + "VALUES ('<id>','<role>');\n"; for (i = 0; i < person.affiliations.length; i++) { var template = "INSERT INTO HR_PEOPLE_ROLES(id, role) " + "VALUES ('<id>','<role>');\n"; if (person.affiliations[i] == 'staff' || person.affiliations[i] == 'faculty' || person.affiliations[i] =='student' || person.affiliations[i] =='community') { temp = template.replace(/<id>/g, person.idNumber); temp = temp.replace(/<role>/g, person.affiliations[i]); output += temp; } } return output; } function selectUnduplicated(source, max) { var output = []; count = rng.nextRange(0, max) + 1; while (output.length < count) { item = source[rng.nextRange(0, source.length)]; if (output.indexOf(item) == -1) { output.push(item); } } return output; } function rankAffiliations(affiliations) { if (affiliations.indexOf("faculty") > -1) return "faculty"; else if (affiliations.indexOf("staff") > -1) return "staff"; else if (affiliations.indexOf("student") > -1) return "student"; else if (affiliations.indexOf("alum") > -1) return "alum"; else return "other"; } function makeQuestionableVpnUsersLists(people) { var csvOutput = ""; var gshOutput = 'addGroup("test", "cisoQuestionableVpnUsersList", "CISO VPN Questionable VPN List");\n'; var sampleCount = 15; for (i = 0; i < people.length && sampleCount > 0; i++) { if (people[i].vpn_user == true & rng.nextFloat() > 0.75) { csvOutput = csvOutput + people[i].uid + "\n"; gshOutput = gshOutput + 'addMember("test:cisoQuestionableVpnUsersList","' + people[i].uid + '");\n'; sampleCount--; } } document.getElementById('vpnCsv').value = csvOutput; document.getElementById('vpnGsh').value = gshOutput; } function makeAthleticsUsersLists(people) { var csvOutput = ""; var gshOutput = 'addGroup("app:mfa:ref", "athletics_dept", "athletics_dept");\n'; var sampleCount = 15; for (i = 0; i < people.length && sampleCount > 0; i++) { if (people[i].affiliations.indexOf('staff') >= 0 & rng.nextFloat() > 0.75) { csvOutput = csvOutput + people[i].uid + "\n"; gshOutput = gshOutput + 'addMember("app:mfa:ref:athletics_dept","' + people[i].uid + '");\n'; sampleCount--; } } document.getElementById('athleticsCsv').value = csvOutput; document.getElementById('athleticsGsh').value = gshOutput; } function makeNonFacultyBannerUsersLists(people) { var csvOutput = ""; var gshOutput = 'addGroup("app:mfa:ref", "NonFacultyBannerINB", "NonFacultyBannerINB");\n'; var sampleCount = 35; for (i = 100; i < people.length && sampleCount > 0; i++) { if (people[i].affiliations.indexOf('staff') >= 0 & rng.nextFloat() > 0.75) { csvOutput = csvOutput + people[i].uid + "\n"; gshOutput = gshOutput + 'addMember("app:mfa:ref:NonFacultyBannerINB","' + people[i].uid + '");\n'; sampleCount--; } } document.getElementById('bannerCsv').value = csvOutput; document.getElementById('bannerGsh').value = gshOutput; } function makeVisitingScholarsLists(people) { var csvOutput = ""; var gshOutput = 'addGroup("app:lms:ref", "visiting_scholars", "visiting_scholars");\n'; var sampleCount = 25; for (i = 300; i < people.length && sampleCount > 0; i++) { if (people[i].affiliations.indexOf('community') >= 0) { csvOutput = csvOutput + people[i].uid + "\n"; gshOutput = gshOutput + 'addMember("app:lms:ref:visiting_scholars","' + people[i].uid + '");\n'; sampleCount--; } } document.getElementById('visitingScholarsCsv').value = csvOutput; document.getElementById('visitingScholarsGsh').value = gshOutput; } </script> </head> <body> <form> Seed: <input type="text" name="seed" id="seed" value="6874" /> <br /> Number of Subjects: <input type="text" name="count" id="count" value="1000" /> <br /> People OU: <input type="text" name="people_ou" id="people_ou" value="ou=people,dc=internet2,dc=edu"/> <br /> <input type="button" onclick="generateData(); return false;" value="Run" /> <br /> </form> <p> Ldif: <br /><textarea cols="100" rows="15" id="ldif"></textarea><br /> </p> <p> Sql: <br /><textarea cols="100" rows="15" id="sql"></textarea> <br /> </p> <p> Questionable VPN Users CSV: <br /><textarea cols="100" rows="15" id="vpnCsv"></textarea> <br /> </p> <p> Questionable VPN Users GSH: <br /><textarea cols="100" rows="15" id="vpnGsh"></textarea> <br /> </p> <p> Athletic Dept CSV: <br /><textarea cols="100" rows="15" id="athleticsCsv"></textarea> <br /> </p> <p> Atheltics Dept GSH: <br /><textarea cols="100" rows="15" id="athleticsGsh"></textarea> <br /> </p> <p> Non-faculty Banner Users CSV: <br /><textarea cols="100" rows="15" id="bannerCsv"></textarea> <br /> </p> <p> Non-faculty Banner Users GSH: <br /><textarea cols="100" rows="15" id="bannerGsh"></textarea> <br /> </p> <p> Visiting Scholars Users CSV: <br /><textarea cols="100" rows="15" id="visitingScholarsCsv"></textarea> <br /> </p> <p> Visiting Scholars Users GSH: <br /><textarea cols="100" rows="15" id="visitingScholarsGsh"></textarea> <br /> </p> </body> </html>