Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tutorial for adding users to ILS db #24

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 219 additions & 0 deletions docs/customize/users.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# Adding Users to Invenio ILS instance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We branded the products InvenioILS and InvenioRDM without spaces:

Suggested change
# Adding Users to Invenio ILS instance
# Adding users to InvenioILS instance

Can you change it everywhere?


This guide provides step-by-step instructions for adding users to a custom Invenio App ILS instance using:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not 100% sure that readers know what is Invenio App ILS, given that we refer to it as InvenioILS:

Suggested change
This guide provides step-by-step instructions for adding users to a custom Invenio App ILS instance using:
This guide provides step-by-step instructions for adding users to your own InvenioILS instance using two possible different methods:


- An existing database
- LDAP synchronization
Comment on lines +5 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are presenting the tutorial in the opposite order (first LDAP, then DB):

Suggested change
- An existing database
- LDAP synchronization
1. LDAP synchronization
2. An existing external database


!!! Note
The following guides are just an example to give you an idea of how you can get started on existing users to your Invenio ILS instance!

Similar scripts can also be used to port other cataloging data like Documents, E-Items, Purchase Orders and more!

This process is suitable for administrators who have just set up a new instance and want to onboard all users to the ILS database.

### Prerequisites

- A running instance of Invenio App ILS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global change:

Suggested change
- A running instance of Invenio App ILS.
- A running instance of InvenioILS.

- Administrative access to the Invenio App ILS instance.
- Python installed on your system.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I have the first, the second prerequisite must be there... I would remove the Python part


## Adding Users to Invenio App ILS Instance using LDAP Sync
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Adding Users to Invenio App ILS Instance using LDAP Sync
## 1. Adding users using LDAP sync


### Step 1: Install LDAP3

First, ensure that the `ldap3` library is installed. You can install it using pip:

```bash
pip install ldap3
```

Make sure you have access to the LDAP directory with user data.

### Step 2: Configure LDAP Connection

Create or update the configuration file for your Invenio App ILS instance to include LDAP connection details. Add the following configuration variables:

```python
LDAP_SERVER = 'ldap://your-ldap-server.com'
LDAP_BIND_USER_DN = 'cn=admin,dc=example,dc=com'
LDAP_BIND_PASSWORD = 'your-bind-password'

LDAP_BASE_DN = 'ou=users,dc=example,dc=com'
LDAP_USER_FILTER = '(objectClass=person)'

LDAP_USER_FIELDS_MAPPING = {
'email': 'mail',
'username': 'uid',
'first_name': 'givenName',
'last_name': 'sn',
}
```

### Step 3: Create a Script for LDAP Sync

Create a Python script to synchronize LDAP users with the Invenio App ILS database. Save the following script as `ldap_sync.py`:

```python
import os
from ldap3 import Server, Connection, ALL
from invenio_accounts.models import User
from invenio_db import db

# Load configuration
LDAP_SERVER = os.getenv('LDAP_SERVER', 'ldap://your-ldap-server.com')
LDAP_BIND_USER_DN = os.getenv('LDAP_BIND_USER_DN', 'cn=admin,dc=example,dc=com')
LDAP_BIND_PASSWORD = os.getenv('LDAP_BIND_PASSWORD', 'your-bind-password')
LDAP_BASE_DN = os.getenv('LDAP_BASE_DN', 'ou=users,dc=example,dc=com')
LDAP_USER_FILTER = os.getenv('LDAP_USER_FILTER', '(objectClass=person)')
LDAP_USER_FIELDS_MAPPING = {
'email': os.getenv('LDAP_FIELD_EMAIL', 'mail'),
'username': os.getenv('LDAP_FIELD_USERNAME', 'uid'),
'first_name': os.getenv('LDAP_FIELD_FIRST_NAME', 'givenName'),
'last_name': os.getenv('LDAP_FIELD_LAST_NAME', 'sn'),
}

def ldap_sync():
# Connect to the LDAP server
server = Server(LDAP_SERVER, get_info=ALL)
conn = Connection(server, LDAP_BIND_USER_DN, LDAP_BIND_PASSWORD, auto_bind=True)

# Search for users
conn.search(LDAP_BASE_DN, LDAP_USER_FILTER, attributes=list(LDAP_USER_FIELDS_MAPPING.values()))

for entry in conn.entries:
# Extract user details
user_data = {field: getattr(entry, ldap_field, [None])[0] for field, ldap_field in LDAP_USER_FIELDS_MAPPING.items()}

# Check if the user already exists
user = User.query.filter_by(email=user_data['email']).first()

if user is None:
# Create a new user
user = User(
email=user_data['email'],
username=user_data['username'],
active=True,
profile=dict(
full_name=f"{user_data['first_name']} {user_data['last_name']}",
),
)
db.session.add(user)
print(f"Added new user: {user.email}")
else:
# Update existing user
user.username = user_data['username']
user.profile['full_name'] = f"{user_data['first_name']} {user_data['last_name']}"
print(f"Updated existing user: {user.email}")

# Commit the changes
db.session.commit()
print("LDAP synchronization complete.")

if __name__ == '__main__':
ldap_sync()
```

## Adding Users to Invenio App ILS Instance from a Custom Database
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Adding Users to Invenio App ILS Instance from a Custom Database
## Adding users from an existing external database


### Step 1: Install Required Packages

Ensure that the required Python packages are installed. You can install them using pip:

```bash
pip install sqlalchemy
```

Make sure you have access to the custom user database.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Make sure you have access to the custom user database.
Make sure you have access to the external user database.


### Step 2: Configure Database Connection

Create a configuration file or environment variables to store your database connection details. Here's an example of setting up a configuration file:

````python
CUSTOM_DB_URI = 'postgresql://user:password@localhost/customdb'
INVENIO_DB_URI = 'postgresql://invenio:password@localhost/invenio'```
````

### Step 3: Create a Script to Port Users
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Step 3: Create a Script to Port Users
### Step 3: Create a script to import users


Create a Python script to read users from the custom database and add them to the Invenio App ILS database. Save the following script as **port_users.py**:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Create a Python script to read users from the custom database and add them to the Invenio App ILS database. Save the following script as **port_users.py**:
Create a Python script to read users from the external database and add them to the InvenioILS database. Save the following script as **import_users.py**:


```python
import os
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker
from invenio_accounts.models import User
from invenio_db import db
from invenio_app.factory import create_api

# Load configuration
custom_db_uri = os.getenv('CUSTOM_DB_URI', 'postgresql://user:password@localhost/customdb')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apply everywhere

Suggested change
custom_db_uri = os.getenv('CUSTOM_DB_URI', 'postgresql://user:password@localhost/customdb')
external_db_uri = os.getenv('CUSTOM_DB_URI', 'postgresql://user:password@localhost/customdb')

invenio_db_uri = os.getenv('INVENIO_DB_URI', 'postgresql://invenio:password@localhost/invenio')

# Create SQLAlchemy engines and sessions
custom_engine = create_engine(custom_db_uri)
invenio_engine = create_engine(invenio_db_uri)

CustomSession = sessionmaker(bind=custom_engine)
InvenioSession = sessionmaker(bind=invenio_engine)

custom_session = CustomSession()
invenio_session = InvenioSession()

# Define the custom user table (adjust to match your schema)
metadata = MetaData()
users_table = Table('users', metadata, autoload_with=custom_engine)

def port_users():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def port_users():
def import_users():

# Query all users from the custom database
custom_users = custom_session.query(users_table).all()

for custom_user in custom_users:
# Extract user details (adjust to match your schema)
email = custom_user.email
username = custom_user.username
first_name = custom_user.first_name
last_name = custom_user.last_name

# Check if the user already exists in Invenio ILS DB
user = invenio_session.query(User).filter_by(email=email).first()

if user is None:
# Create a new user
user = User(
email=email,
username=username,
active=True,
profile=dict(
full_name=f"{first_name} {last_name}",
),
)
invenio_session.add(user)
print(f"Added new user: {email}")
else:
# Update existing user
user.username = username
user.profile['full_name'] = f"{first_name} {last_name}"
print(f"Updated existing user: {email}")

# Commit the changes
invenio_session.commit()
print("User porting complete.")

if __name__ == '__main__':
# Initialize Invenio app context
app = create_api()
with app.app_context():
port_users()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
port_users()
import_users()


# Close sessions
custom_session.close()
invenio_session.close()
```

### Additional Tips

You may schedule the script to run periodically (e.g., using a cron job) if you need to keep the Invenio user database in sync with your custom database/LDAP directory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You may schedule the script to run periodically (e.g., using a cron job) if you need to keep the Invenio user database in sync with your custom database/LDAP directory.
You may schedule the script to run periodically (e.g., using a cron job) if you need to keep the InvenioILS user database in sync with your external database or LDAP directory.


Feel free to adjust the configurations and script to better fit your specific environment and requirements.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ nav:
- Local development: customize/develop.md
- Static pages: customize/static_pages.md
- User anonymization: customize/anonymization.md
- Adding Users to the instance: customize/users.md
- Vocabularies: customize/vocabularies.md
- Reference:
- Understanding data model: reference/data_model.md
Expand Down