From 8e3acfbe56a13eb5edd0aca2a2ab12be440a0555 Mon Sep 17 00:00:00 2001 From: George Peppard <gjp1g21@soton.ac.uk> Date: Fri, 15 Oct 2021 18:12:21 +0100 Subject: [PATCH] actually add code --- README.md | 16 +- pom.xml | 29 +++- .../ecsuserfetcher/EcsUserFetcher.java | 158 +++++++++++++++++- .../com/gpeppard/ecsuserfetcher/Main.java | 2 +- .../ecsuserfetcher/models/Person.java | 76 +++++++++ .../gpeppard/ecsuserfetcher/models/User.java | 4 - src/test/java/com/gpeppard/AppTest.java | 20 --- 7 files changed, 266 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/gpeppard/ecsuserfetcher/models/Person.java delete mode 100644 src/main/java/com/gpeppard/ecsuserfetcher/models/User.java delete mode 100644 src/test/java/com/gpeppard/AppTest.java diff --git a/README.md b/README.md index 3c8f16f..1daaad1 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,10 @@ The `-u` and `-p` parameters are required, as is the username to query (obviously). The information above can be displayed at any time by running the software with the `-?` or `--help` arguments. +If you do not want to give the program your password in plain text (you shouldn't) +then you can use an encrypted form by prefixing it with `{crypt}` and +encrypting it by following [these instructions](https://www.openldap.org/faq/data/cache/344.html). + ## License and limitation of liability This program is free software: you can redistribute it and/or modify @@ -57,4 +61,14 @@ file. To put it briefly, I was not sure how the University would react to me using their LDAP server for this purpose (although one could argue that if they didn't want me to use it, then I should not have access!), hence -the project can only be viewed internally on the University's Git service. \ No newline at end of file +the project can only be viewed internally on the University's Git service. + +## Things that could be improved + +As there is no reason anyone would actually use this software, there is +no real reason to modify it in the future. The following is a list of things +that could be improved to make the software better. + +- Right now it is not possible to specify the LDAP server hostname or port. +This means if the University decides to change their hostname or port, the +program will break. diff --git a/pom.xml b/pom.xml index 99ec00e..6d0f5d6 100644 --- a/pom.xml +++ b/pom.xml @@ -13,8 +13,8 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.source>1.17</maven.compiler.source> - <maven.compiler.target>1.17</maven.compiler.target> + <maven.compiler.source>17</maven.compiler.source> + <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> @@ -58,8 +58,17 @@ <version>2.22.1</version> </plugin> <plugin> - <artifactId>maven-jar-plugin</artifactId> - <version>3.0.2</version> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>com.gpeppard.ecsuserfetcher.Main</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> @@ -78,16 +87,20 @@ <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.0.0</version> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>3.3.1</version> + <configuration> + <show>private</show> + </configuration> + </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <source>17</source> - <target>17</target> - </configuration> </plugin> </plugins> </build> diff --git a/src/main/java/com/gpeppard/ecsuserfetcher/EcsUserFetcher.java b/src/main/java/com/gpeppard/ecsuserfetcher/EcsUserFetcher.java index c58b760..c06dcc1 100644 --- a/src/main/java/com/gpeppard/ecsuserfetcher/EcsUserFetcher.java +++ b/src/main/java/com/gpeppard/ecsuserfetcher/EcsUserFetcher.java @@ -1,9 +1,21 @@ package com.gpeppard.ecsuserfetcher; +import com.gpeppard.ecsuserfetcher.models.Person; +import org.apache.directory.api.ldap.model.cursor.CursorException; +import org.apache.directory.api.ldap.model.cursor.EntryCursor; +import org.apache.directory.api.ldap.model.entry.Entry; +import org.apache.directory.api.ldap.model.exception.LdapException; +import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException; +import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.ldap.client.api.LdapConnection; +import org.apache.directory.ldap.client.api.LdapNetworkConnection; + +import java.io.IOException; + /** * A single instance of the program. * - * @author George Peppard <gjp1g21@soton.ac.uk> + * @author George Peppard {@literal <gjp1g21@soton.ac.uk>} */ public class EcsUserFetcher { private final String ldapUsername; @@ -12,9 +24,9 @@ public class EcsUserFetcher { private final boolean detailed; /** - * Constructs a new instance of SCWebScraper. + * Constructs a new instance of EcsUserFetcher. * - * We do not want everything to be static so instead, we use this object instead to hold (or + * <p>We do not want everything to be static so instead, we use this object instead to hold (or * call) the majority of program code. * * @param ldapUsername the LDAP username of the user accessing the data @@ -29,10 +41,146 @@ public class EcsUserFetcher { this.detailed = detailed; } + /** Run the application. */ + public void run() { + Person person = fetchUser(query); + + if (person == null) { + System.err.println("There was an error whilst trying to fetch this user."); + return; + } + + outputUserInformation(person); + } + /** - * Run the application. + * Fetches a {@link Person} from the LDAP server. + * + * @param mailNickname the mailNickname attribute of the person you want to search for + * @return the Person who has been returned, or {@code null} if they do not exist or an error occurs */ - public void run() { + private Person fetchUser(String mailNickname) { + /* Connect to the LDAP server and bind credentials */ + LdapConnection connection = new LdapNetworkConnection("ldap.soton.ac.uk", 389); + try { + connection.bind(ldapUsername, ldapPassword); + } catch (LdapException e) { + System.err.println("Failed to connect to the LDAP server: " + e.getMessage()); + System.err.println("Are your credentials correct?"); + + try { + connection.close(); + } catch(IOException ex) { + ex.printStackTrace(); + } + + return null; + } + + /* Search for the user by mailNickname */ + EntryCursor cur; + try { + cur = connection.search( + "OU=fp,OU=fp,OU=ek,OU=User,DC=soton,DC=ac,DC=uk", "(mailNickname=" + query + ")", SearchScope.SUBTREE, "*"); + } catch(LdapException e) { + try { + connection.close(); + } catch(IOException ex) { + ex.printStackTrace(); + } + + System.err.println("An error occurred whilst searching for the user: " + e.getMessage()); + return null; + } + + /* Check to make sure this object exists */ + try { + if (!cur.next()) { + System.err.println("There were no results for that email nickname. Does the user exist?"); + + try { + connection.close(); + } catch(IOException ex) { + ex.printStackTrace(); + } + + return null; + } + } catch(LdapException | CursorException e) { + /* this should never happen */ + e.printStackTrace(); + return null; + } + + /* Get first (there should only ever be one) object from server and then close connection */ + Entry entry; + try { + entry = cur.get(); + } catch(CursorException e) { + /* this should never happen so we just print the stack trace */ + e.printStackTrace(); + try { + connection.close(); + } catch(IOException ex) { + ex.printStackTrace(); + } + + return null; + } + + try { + connection.unBind(); + connection.close(); + } catch (LdapException | IOException e) { + System.err.println("An exception occurred when closing the LDAP connection: " + e.getMessage()); + } + + /* Move information from the LDAP object into a new Person */ + Person person; + try { + person = new Person( + entry.get("mailNickname").getString(), + entry.get("givenName").getString(), + entry.get("sn").getString(), + entry.get("title").getString(), + entry.get("department").getString() + ); + } catch (LdapInvalidAttributeValueException e) { + System.err.println("Could not get required attributes for this person. Is it an actual person?"); + return null; + } + + /* Return the Person */ + return person; + } + + /** + * Outputs the user information to the console. + */ + private void outputUserInformation(Person person) { + if (detailed) { + outputDetailedUserInformation(person); + } else { + outputBriefUserInformation(person); + } + } + + /** + * Outputs the user name to the console. + */ + private void outputBriefUserInformation(Person person) { + System.out.println("User: " + person.getMailName()); + System.out.println("Full name: " + person.getGivenName() + " " + person.getSurname()); + } + + /** + * Outputs detailed user information to the console. + */ + private void outputDetailedUserInformation(Person person) { + System.out.println("User: " + person.getMailName()); + System.out.println("Full name: " + person.getGivenName() + " " + person.getSurname()); + System.out.println("Position title: " + person.getJobTitle()); + System.out.println("Department: " + person.getDepartment()); } } diff --git a/src/main/java/com/gpeppard/ecsuserfetcher/Main.java b/src/main/java/com/gpeppard/ecsuserfetcher/Main.java index 324352f..3a41ba4 100644 --- a/src/main/java/com/gpeppard/ecsuserfetcher/Main.java +++ b/src/main/java/com/gpeppard/ecsuserfetcher/Main.java @@ -5,7 +5,7 @@ import org.apache.commons.cli.*; /** * Main application class. * - * @author George Peppard <gjp1g21@soton.ac.uk> + * @author George Peppard {@literal <gjp1g21@soton.ac.uk>} */ public class Main { /** diff --git a/src/main/java/com/gpeppard/ecsuserfetcher/models/Person.java b/src/main/java/com/gpeppard/ecsuserfetcher/models/Person.java new file mode 100644 index 0000000..41d2d57 --- /dev/null +++ b/src/main/java/com/gpeppard/ecsuserfetcher/models/Person.java @@ -0,0 +1,76 @@ +package com.gpeppard.ecsuserfetcher.models; + +/** + * A single person whose data is stored in the LDAP server. + * + * @author George Peppard {@literal <gjp1g21@soton.ac.uk>} + */ +public class Person { + private final String mailName; + private final String givenName; + private final String surname; + private final String jobTitle; + private final String department; + + /** + * Constructs a new instance of {@code Person}. + * + * @param mailName the mail nickname of the person + * @param givenName the first name of the person + * @param surname the surname of the person + * @param jobTitle the position title of the person + * @param department the department of the person + */ + public Person(String mailName, String givenName, String surname, String jobTitle, String department) { + this.mailName = mailName; + this.givenName = givenName; + this.surname = surname; + this.jobTitle = jobTitle; + this.department = department; + } + + /** + * Gets the mail nickname of the person. + * + * @return the mail nickname of the person + */ + public String getMailName() { + return mailName; + } + + /** + * Gets the first name of the person. + * + * @return the first name of the person + */ + public String getGivenName() { + return givenName; + } + + /** + * Gets the surname of the person. + * + * @return the surname of the person + */ + public String getSurname() { + return surname; + } + + /** + * Gets the position title of the person. + * + * @return the position title of the person + */ + public String getJobTitle() { + return jobTitle; + } + + /** + * Gets the department of the person. + * + * @return the department of the person + */ + public String getDepartment() { + return department; + } +} diff --git a/src/main/java/com/gpeppard/ecsuserfetcher/models/User.java b/src/main/java/com/gpeppard/ecsuserfetcher/models/User.java deleted file mode 100644 index 6c826d9..0000000 --- a/src/main/java/com/gpeppard/ecsuserfetcher/models/User.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.gpeppard.ecsuserfetcher.models; - -public class User { -} diff --git a/src/test/java/com/gpeppard/AppTest.java b/src/test/java/com/gpeppard/AppTest.java deleted file mode 100644 index c69dcf3..0000000 --- a/src/test/java/com/gpeppard/AppTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gpeppard; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -/** - * Unit test for simple App. - */ -public class AppTest -{ - /** - * Rigorous Test :-) - */ - @Test - public void shouldAnswerWithTrue() - { - assertTrue( true ); - } -} -- GitLab