Skip to content

Commit

Permalink
🌟Synchronization of the user with LDAP
Browse files Browse the repository at this point in the history
  • Loading branch information
shepilov committed Sep 6, 2023
1 parent 666f51e commit f97d62c
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/ldap-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: backend-build

on:
pull_request:
branches: [main]
paths:
- "tdrive/utils/ldap-sync/**"

jobs:
publish-node:
runs-on: ubuntu-20.04
steps:
- name: Set env to production
if: endsWith(github.ref, '/main')
run: 'echo "DOCKERTAG=latest" >> $GITHUB_ENV'
- name: "Push to the registry following labels:"
run: |
echo "${{ env.DOCKERTAG }},${{ env.DOCKERTAGVERSION }}"
- uses: actions/checkout@v2
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@v5
with:
name: tdrive/tdrive-ldap-sync
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
workdir: tdrive
registry: docker-registry.linagora.com
context: .
target: production
buildoptions: "-t docker-registry.linagora.com/tdrive/tdrive-ldap-sync -f docker/tdrive-ldap-sync/Dockerfile"
tags: "${{ env.DOCKERTAG }},${{ env.DOCKERTAGVERSION }}"
6 changes: 6 additions & 0 deletions tdrive/backend/utils/ldap-sync/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
LDAP_URL=ldap://localhost:389
LDAP_BIND_DN=
LDAP_BIND_CREDENTIALS=
LDAP_SEARCH_BASE=dc=example,dc=com
LDAP_SEARCH_FILTER=(objectClass=inetorgperson)
API_URL=http://tdrive:4000/api/sync
1 change: 1 addition & 0 deletions tdrive/backend/utils/ldap-sync/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
26 changes: 26 additions & 0 deletions tdrive/backend/utils/ldap-sync/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "ldap_project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "npm run build:clean && npm run build:ts",
"build:ts": "tsc",
"build:clean": "rimraf ./dist",
"sync": "node dist/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.4.0",
"dotenv": "^16.0.3",
"ldapjs": "^3.0.2"
},
"devDependencies": {
"@types/ldapjs": "^2.2.5",
"typescript": "^5.0.4",
"rimraf": "^3.0.2"
}
}
96 changes: 96 additions & 0 deletions tdrive/backend/utils/ldap-sync/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import ldap from "ldapjs";
import axios from "axios";
import dotenv from "dotenv";

interface UserAttributes {
first_name: string;
last_name: string;
email: string;
}

dotenv.config();

console.log("Run script with the following env: ");
console.log(process.env);

// LDAP server configuration
const ldapConfig = {
url: process.env.LDAP_URL|| "localhost",
bindDN: process.env.LDAP_BIND_DN || "",
bindCredentials: process.env.LDAP_BIND_CREDENTIALS || "",
searchBase: process.env.LDAP_SEARCH_BASE || "dc=example,dc=com",
searchFilter: process.env.LDAP_SEARCH_FILTER || "(objectClass=inetorgperson)",
timeout: 120,
version: 3,
};

// Create LDAP client
const client = ldap.createClient({
url: ldapConfig.url,
});

// Bind to LDAP server
client.bind(ldapConfig.bindDN, ldapConfig.bindCredentials, (err) => {
if (err) {
console.error("LDAP bind error:", err);
return;
}

// Perform search
client.search(
ldapConfig.searchBase,
{
filter: ldapConfig.searchFilter,
attributes: ["uid", "mail", "cn", "sn", "mobile"],
scope: "sub",
derefAliases: 2,
},
(searchErr, searchRes) => {
if (searchErr) {
console.error("LDAP search error:", searchErr);
return;
}

const apiRequests: Promise<any>[] = [];

searchRes.on("searchEntry", (entry: any) => {
// Handle each search result entry
const userAttributes: UserAttributes = {
first_name: entry.attributes[1]?.values[0],
last_name: entry.attributes[2]?.values[0],
email: entry.attributes[3]?.values[0],
};

// Make API call to tdrive backend with the userAttributes
apiRequests.push(axios.post(process.env.API_URL || "", userAttributes));
});

searchRes.on("error", (err) => {
console.error("LDAP search result error:", err);
});

searchRes.on("end", () => {
// Unbind from LDAP server after search is complete
client.unbind((unbindErr) => {
if (unbindErr) {
console.error("LDAP unbind error:", unbindErr);
} else {
Promise.all(apiRequests)
.then((responses) => {
console.log(
"API responses:",
responses.map((r) => r.data)
);
})
.catch((error) => {
console.error("API error:", error);
})
.finally(() => {
console.log("LDAP search completed successfully.");
});
}
});
});
}
);
});
11 changes: 11 additions & 0 deletions tdrive/backend/utils/ldap-sync/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}

15 changes: 15 additions & 0 deletions tdrive/docker/tdrive-ldap-sync/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Use an official Node.js runtime as the base image
FROM node:lts-alpine

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy app
COPY backend/utils/ldap-sync/*.json ./
COPY backend/utils/ldap-sync/src/** ./src/
COPY backend/utils/ldap-sync/.nvmrc ./

RUN npm i && npm run build

# Run the Node.js application
CMD ["npm", "run", "sync"]

0 comments on commit f97d62c

Please sign in to comment.