Skip to content

Commit

Permalink
Merge pull request #1 from TGM-HIT/modular
Browse files Browse the repository at this point in the history
Make Modular the default approach + AD LDAP connection
  • Loading branch information
mpointner authored Oct 10, 2024
2 parents bbca948 + 5e3194d commit 887c9ef
Show file tree
Hide file tree
Showing 23 changed files with 534 additions and 66 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ out/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

.env
34 changes: 26 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,32 @@ Gemeinsames Spring Boot Backend für Diplomarbeitsprojekte

Getestet mit:

- SDK Eclipse Temurin (AdoptOpenJDK HotSpot) 21.0.4 und Amazon Corretto 17.0.12
- SDK Eclipse Temurin (AdoptOpenJDK HotSpot) 21.0.4
- Gradle 8.10.1

## Enthaltene Spring Abhändigkeiten
Für die Active Directory LDAP Anbindung muss auf der Root eine `.env` Datei angelegt werden, welche Folgendes enthält:

- Spring Boot DevTools
- Lombok
- Spring Web
- Spring Data JPA
- H2 Database
- Validation
```
AD_USER=insertTGMEmailAdressHere
AD_PASSWORD=insertTGMPasswortHere
```

## Gradle Projektstruktur

Die angedachte Struktur ist folgende:

- Im **server** Modul wird
- der Tomcat gestartet
- im SecurityConfig die Pfade konfiguriert, bei denen ein Login notwendig ist.
- alle enthalten Projekte (und core) im `implementation project(':beispielprojekt')` importiert
- Das **beispiel** -Modul ist eine Vorlage für ein Modul, wo eine Diplomarbeit ihren spezifischen Code entwickeln soll.
- **core**: Alle Module importieren dies und hier soll auch der von mehreren Projekten genutzte Code wie z.B. Active Directory LDAP Anbindung reinkommen

## Beispiel-API-Endpoints

### Active Directory LDAP Anbindung

- [Eingeloggter User](http://localhost:8080/beispielprojekt)
- [HIT-Schueler auflisten](http://localhost:8080/beispielprojekt/list/schueler)
- [Lehrer auflisten](http://localhost:8080/beispielprojekt/list/lehrer)
- [Person anhand des Nachnamen suchen](http://localhost:8080/beispielprojekt/find/Pointner)
3 changes: 3 additions & 0 deletions beispiel/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
implementation project(':core')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package at.ac.tgm.controller;

import at.ac.tgm.ad.entry.UserEntry;
import at.ac.tgm.ad.service.UserService;
import at.ac.tgm.ad.util.EntryBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.naming.Name;
import java.util.List;

@RestController
@RequestMapping("/beispielprojekt")
public class HelloWorldController {

@Autowired
private UserService userService;

@GetMapping({"", "/"})
public Authentication getAuthCurrentUser() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return auth;
}

@GetMapping("/list/lehrer")
public List<String> listLehrer() {
return userService.listUserCNs(EntryBase.LEHRER);
}

@GetMapping("/find/{surname}")
public ResponseEntity<UserEntry> findUser(@PathVariable("surname") String surname) {
return ResponseEntity.of(userService.findBySurname(surname, true));
}

@GetMapping("/list/schueler")
public List<Name> entities() {
return userService.listUserDNs(EntryBase.SCHUELER_HIT);
}

}
80 changes: 46 additions & 34 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.3.3'
id 'io.spring.dependency-management' version '1.1.6'
id 'org.springframework.boot' version '3.3.4'
}

group = 'at.ac.tgm'
version = '0.0.1-SNAPSHOT'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
allprojects{
group = 'at.ac.tgm'
version = '0.0.1-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
}

configurations {
compileOnly {
extendsFrom annotationProcessor
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
useJUnitPlatform()
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

}

tasks.named('test') {
useJUnitPlatform()
}

bootJar.enabled = false
bootWar.enabled = false
}
24 changes: 24 additions & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
plugins {
id 'java'
}

group = 'at.ac.tgm'
version = 'unspecified'

repositories {
mavenCentral()
}

dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'

implementation 'org.springframework.ldap:spring-ldap-core'
implementation 'org.springframework.security:spring-security-ldap'
implementation 'org.springframework.boot:spring-boot-starter-data-ldap'
implementation 'com.unboundid:unboundid-ldapsdk'
}

test {
useJUnitPlatform()
}
51 changes: 51 additions & 0 deletions core/src/main/java/at/ac/tgm/ad/entry/GroupEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package at.ac.tgm.ad.entry;

import at.ac.tgm.ad.util.EntryBase;
import lombok.*;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;

import javax.naming.Name;
import java.util.List;
import java.util.Set;

@Entry(
base = EntryBase.GROUP,
objectClasses = { "group", "top" })
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString
public class GroupEntry {
private @Id Name dn;
private @Attribute(name = "cn") String cn;
private @Attribute(name = "displayName") String displayName;
private @Attribute(name = "distinguishedName") String distinguishedName;
private @Attribute(name = "dSCorePropagationData") List<String> dSCorePropagationData;
private @Attribute(name = "groupType") String groupType;
private @Attribute(name = "instanceType") String instanceType;
private @Attribute(name = "legacyExchangeDN") String legacyExchangeDN;
private @Attribute(name = "mail") String mail;
private @Attribute(name = "mailNickname") String mailNickname;
private @Attribute(name = "member") Set<Name> member;
private @Attribute(name = "memberOf") Name memberOf;
private @Attribute(name = "msExchGroupExternalMemberCount") String msExchGroupExternalMemberCount;
private @Attribute(name = "msExchGroupMemberCount") String msExchGroupMemberCount;
private @Attribute(name = "msExchPoliciesIncluded") List<String> msExchPoliciesIncluded;
private @Attribute(name = "msExchRecipientDisplayType") String msExchRecipientDisplayType;
private @Attribute(name = "msExchRequireAuthToSendTo") String msExchRequireAuthToSendTo;
private @Attribute(name = "msExchUMDtmfMap") List<String> msExchUMDtmfMap;
private @Attribute(name = "msExchVersion") String msExchVersion;
private @Attribute(name = "name") String name;
private @Attribute(name = "objectCategory") String objectCategory;
private @Attribute(name = "objectClass") List<String> objectClass;
private @Attribute(name = "objectGUID") String objectGUID;
private @Attribute(name = "objectSid") String objectSid;
private @Attribute(name = "proxyAddresses") List<String> proxyAddresses;
private @Attribute(name = "reportToOriginator") String reportToOriginator;
private @Attribute(name = "sAMAccountName") String sAMAccountName;
private @Attribute(name = "sAMAccountType") String sAMAccountType;
private @Attribute(name = "showInAddressBook") List<String> showInAddressBook;
private @Attribute(name = "uSNChanged") String uSNChanged;
private @Attribute(name = "uSNCreated") String uSNCreated;
private @Attribute(name = "whenChanged") String whenChanged;
private @Attribute(name = "whenCreated") String whenCreated;
}
96 changes: 96 additions & 0 deletions core/src/main/java/at/ac/tgm/ad/entry/UserEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package at.ac.tgm.ad.entry;

import at.ac.tgm.ad.util.EntryBase;
import lombok.*;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import org.springframework.ldap.odm.annotations.Transient;

import javax.naming.Name;
import java.util.List;
import java.util.Set;

@Entry(base = EntryBase.LEHRER, objectClasses = {"user", "organizationalPerson", "person", "top"})
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class UserEntry {
private @Id Name id;
private @Attribute(name = "memberOf") Set<Name> memberOf;
private @Transient Set<GroupEntry> groups;
private @Attribute(name = "cn") String cn;
private @Attribute(name = "sn") String sn;
private @Attribute(name = "accountExpires") String accountExpires;
private @Attribute(name = "badPasswordTime") String badPasswordTime;
private @Attribute(name = "badPwdCount") String badPwdCount;
private @Attribute(name = "codePage") String codePage;
private @Attribute(name = "countryCode") String countryCode;
private @Attribute(name = "displayName") String displayName;
private @Attribute(name = "distinguishedName") String distinguishedName;
private @Attribute(name = "dSCorePropagationData") List<String> dSCorePropagationData;
private @Attribute(name = "employeeNumber") String employeeNumber;
private @Attribute(name = "employeeType") String employeeType;
private @Attribute(name = "extensionAttribute2") String extensionAttribute2;
private @Attribute(name = "extensionAttribute4") String extensionAttribute4;
private @Attribute(name = "extensionAttribute5") String extensionAttribute5;
private @Attribute(name = "givenName") String givenName;
private @Attribute(name = "homeDirectory") String homeDirectory;
private @Attribute(name = "homeDrive") String homeDrive;
private @Attribute(name = "homeMDB") String homeMDB;
private @Attribute(name = "info") String info;
private @Attribute(name = "instanceType") String instanceType;
private @Attribute(name = "l") String l;
private @Attribute(name = "lastLogoff") String lastLogoff;
private @Attribute(name = "lastLogon") String lastLogon;
private @Attribute(name = "lastLogonTimestamp") String lastLogonTimestamp;
private @Attribute(name = "legacyExchangeDN") String legacyExchangeDN;
private @Attribute(name = "logonCount") String logonCount;
private @Attribute(name = "mail") String mail;
private @Attribute(name = "mailNickname") String mailNickname;
private @Attribute(name = "mDBUseDefaults") String mDBUseDefaults;
private @Attribute(name = "mS-DS-ConsistencyGuid") String mSDSConsistencyGuid;
private @Attribute(name = "msDS-ExternalDirectoryObjectId") String msDSExternalDirectoryObjectId;
private @Attribute(name = "msExchArchiveQuota") String msExchArchiveQuota;
private @Attribute(name = "msExchArchiveWarnQuota") String msExchArchiveWarnQuota;
private @Attribute(name = "msExchCalendarLoggingQuota") String msExchCalendarLoggingQuota;
private @Attribute(name = "msExchDumpsterQuota") String msExchDumpsterQuota;
private @Attribute(name = "msExchDumpsterWarningQuota") String msExchDumpsterWarningQuota;
private @Attribute(name = "msExchELCMailboxFlags") String msExchELCMailboxFlags;
private @Attribute(name = "msExchHideFromAddressLists") String msExchHideFromAddressLists;
private @Attribute(name = "msExchHomeServerName") String msExchHomeServerName;
private @Attribute(name = "msExchMailboxGuid") String msExchMailboxGuid;
private @Attribute(name = "msExchMailboxSecurityDescriptor") String msExchMailboxSecurityDescriptor;
private @Attribute(name = "msExchMobileMailboxFlags") String msExchMobileMailboxFlags;
private @Attribute(name = "msExchPoliciesIncluded") String msExchPoliciesIncluded;
private @Attribute(name = "msExchRBACPolicyLink") String msExchRBACPolicyLink;
private @Attribute(name = "msExchRecipientDisplayType") String msExchRecipientDisplayType;
private @Attribute(name = "msExchRecipientTypeDetails") String msExchRecipientTypeDetails;
private @Attribute(name = "msExchSafeSendersHash") String msExchSafeSendersHash;
private @Attribute(name = "msExchSharingAnonymousIdentities") String msExchSharingAnonymousIdentities;
private @Attribute(name = "msExchTextMessagingState") List<String> msExchTextMessagingState;
private @Attribute(name = "msExchUMDtmfMap") List<String> msExchUMDtmfMap;
private @Attribute(name = "msExchUserAccountControl") String msExchUserAccountControl;
private @Attribute(name = "msExchUserCulture") String msExchUserCulture;
private @Attribute(name = "msExchVersion") String msExchVersion;
private @Attribute(name = "msExchWhenMailboxCreated") String msExchWhenMailboxCreated;
private @Attribute(name = "name") String name;
private @Attribute(name = "objectCategory") String objectCategory;
private @Attribute(name = "objectClass") List<String> objectClass;
private @Attribute(name = "objectGUID") String objectGUID;
private @Attribute(name = "objectSid") String objectSid;
private @Attribute(name = "primaryGroupID") String primaryGroupID;
private @Attribute(name = "profilePath") String profilePath;
private @Attribute(name = "protocolSettings") String protocolSettings;
private @Attribute(name = "proxyAddresses") List<String> proxyAddresses;
private @Attribute(name = "pwdLastSet") String pwdLastSet;
private @Attribute(name = "sAMAccountName") String sAMAccountName;
private @Attribute(name = "sAMAccountType") String sAMAccountType;
private @Attribute(name = "showInAddressBook") List<Name> showInAddressBook;
private @Attribute(name = "userAccountControl") String userAccountControl;
private @Attribute(name = "userPrincipalName") String userPrincipalName;
private @Attribute(name = "uSNChanged") String uSNChanged;
private @Attribute(name = "uSNCreated") String uSNCreated;
}
12 changes: 12 additions & 0 deletions core/src/main/java/at/ac/tgm/ad/repository/GroupRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package at.ac.tgm.ad.repository;

import at.ac.tgm.ad.entry.GroupEntry;
import org.springframework.data.ldap.repository.LdapRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface GroupRepository extends LdapRepository<GroupEntry> {
Optional<GroupEntry> findByCn(String cn);
}
Loading

0 comments on commit 887c9ef

Please sign in to comment.