Users
Users are the core authentication and authorization entities in Taruvi Cloud. Each user can belong to multiple organizations and have access to multiple sites with different permission levels.
All user endpoints use username-based URLs (e.g., /api/cloud/users/john.doe/) for accessing and managing user resources. UUIDs are still supported for identification purposes.
Overview
A user represents an individual account in Taruvi Cloud. Users can:
- Authenticate: Login via JWT, session, or OAuth
- Multi-Organization: Belong to multiple organizations
- Multi-Tenant: Access multiple sites with different permissions
- Role-Based: Have different roles and permissions per organization/site
- Profile Management: Manage personal information and settings
Key Features
Authentication
Taruvi supports multiple authentication methods:
- JWT Tokens: Stateless authentication for APIs
- Session Auth: Cookie-based for browsable API
- OAuth/Social: Google, GitHub, and other providers
Multi-Organization Membership
Users can be members of multiple organizations:
- Different roles per organization
- Independent permissions per organization
- Cross-organization collaboration
Site Access
Users can access multiple sites within organizations:
- Site-specific permissions
- Tenant-aware operations
- Isolated data access per site
Soft Delete
Users are soft-deleted for audit trail:
is_active: Controls login accessis_deleted: Marks as deleted but preserves data- Restoration capability
User Model
Fields
| Field | Type | Description |
|---|---|---|
id | integer | Primary key |
uuid | UUID | Unique identifier (read-only) |
username | string | Unique username (required, used in URLs) |
email | string | Email address (required, unique) |
first_name | string | First name (optional) |
last_name | string | Last name (optional) |
is_active | boolean | User can login |
is_staff | boolean | Admin access |
is_superuser | boolean | Full permissions |
is_deleted | boolean | Soft delete flag |
date_joined | datetime | Account creation date (read-only) |
last_login | datetime | Last login timestamp (read-only) |
Using Users
Listing Users
Get all users:
- REST API
- Python
- JavaScript
curl -X GET "https://your-site.taruvi.cloud/api/cloud/users/?organization_slug=acme-corp&is_active=true" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK):
{
"count": 25,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"username": "john.doe",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"is_active": true,
"is_staff": false,
"is_superuser": false,
"is_deleted": false,
"date_joined": "2024-01-15T10:30:00Z"
}
]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/",
headers=headers,
params={"organization_slug": "acme-corp", "is_active": "true"}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/?organization_slug=acme-corp&is_active=true", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Query Parameters:
search: Search by username, email, nameis_active: Filter by active status (true,false, orall)is_staff: Filter by staff statusorganization_slug: Filter by organization membershiporganization_uuid: Filter by organization UUID (alternative to slug)ordering: Sort results (e.g.,username,-date_joined)
When filtering by organization, visibility depends on your role:
- Organization Admin/Owner: See all members in the organization
- User with
manage_organizationpermission: See all members - Regular member: See only yourself
- No organization filter +
view_userpermission: See all users - No organization filter + no permission: See only yourself
Creating a User
Create a new user account:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/users/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"username": "jane.smith",
"email": "[email protected]",
"password": "SecurePassword123!",
"first_name": "Jane",
"last_name": "Smith"
}'
Response (201 Created):
{
"id": 2,
"uuid": "650e8400-e29b-41d4-a716-446655440001",
"username": "jane.smith",
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Smith",
"is_active": true,
"is_deleted": false,
"date_joined": "2024-01-20T14:20:00Z"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/users/",
headers=headers,
json={
"username": "jane.smith",
"email": "[email protected]",
"password": "SecurePassword123!",
"first_name": "Jane",
"last_name": "Smith"
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
username: "jane.smith",
email: "[email protected]",
password: "SecurePassword123!",
first_name: "Jane",
last_name: "Smith"
})
})
const data = await response.json()
Retrieving User Details
Get details of a specific user:
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK):
{
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"username": "john.doe",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"is_active": true,
"is_staff": false,
"is_superuser": false,
"is_deleted": false,
"date_joined": "2024-01-15T10:30:00Z",
"organizations": [
{
"slug": "acme-corp",
"name": "Acme Corporation",
"role": "member"
}
]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Updating a User
Update user information:
- REST API
- Python
- JavaScript
curl -X PUT https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]"
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.put(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers,
json={
"first_name": "John",
"last_name": "Smith",
"email": "[email protected]"
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
first_name: "John",
last_name: "Smith",
email: "[email protected]"
})
})
const data = await response.json()
Partial update:
- REST API
- Python
- JavaScript
curl -X PATCH https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"first_name": "Johnny"}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.patch(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers,
json={"first_name": "Johnny"}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ first_name: "Johnny" })
})
const data = await response.json()
Deleting a User (Soft Delete)
Soft delete a user:
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers
)
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
User deletion is a soft delete operation:
- Sets
is_deleted=trueandis_active=false - User data is preserved for audit trail
- User cannot login after deletion
- All organization memberships are removed (hard deleted)
- Users cannot delete themselves
- Non-superusers cannot delete superusers
Deactivating a User
Deactivate without deleting:
- REST API
- Python
- JavaScript
curl -X PATCH https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"is_active": false}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.patch(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers,
json={"is_active": False}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ is_active: false })
})
const data = await response.json()
Organization Membership
Adding User to Organization
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"user_id": "john.doe"}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers,
json={"user_id": "john.doe"}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ user_id: "john.doe" })
})
const data = await response.json()
Listing Organization Members
- REST API
- Python
- JavaScript
curl -X GET https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Removing User from Organization
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/",
headers=headers
)
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/john.doe/", {
method: "DELETE",
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
Site Permissions
Users can have specific permissions for sites within organizations:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"user_id": "john.doe",
"sites": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
},
{
"slug": "staging-site",
"permissions": ["view_site"]
}
]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers,
json={
"user_id": "john.doe",
"sites": [
{
"slug": "production-site",
"permissions": ["view_site", "manage_site"]
},
{
"slug": "staging-site",
"permissions": ["view_site"]
}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
user_id: "john.doe",
sites: [
{
slug: "production-site",
permissions: ["view_site", "manage_site"]
},
{
slug: "staging-site",
permissions: ["view_site"]
}
]
})
})
const data = await response.json()
User-Site Relationship Management
Taruvi provides bidirectional APIs to manage user-site relationships using django-guardian permissions. These APIs allow you to:
- User → Sites: Manage which sites a user can access
- Site → Users: Manage which users have access to a site
You can manage the same relationships from either direction:
/api/cloud/users/{username}/sites/- Manage sites for a specific user/api/cloud/sites/{site_slug}/users/- Manage users for a specific site
User → Sites API
Manage site assignments for a specific user.
List User's Sites
Get all sites a user has access to with their permissions:
- REST API
- Python
- JavaScript
curl -X GET "https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/?search=production" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK):
{
"success": true,
"data": [
{
"slug": "production-site",
"name": "Production Site",
"permissions": ["view_site", "access_site"]
},
{
"slug": "staging-site",
"name": "Staging Site",
"permissions": ["view_site"]
}
],
"total": 2,
"message": "User sites retrieved successfully"
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
params={"search": "production"}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/?search=production", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Query Parameters:
search: Search by site name (case-insensitive)name: Filter by exact site namename__contains: Filter by name containing string
Add Sites to User
Add multiple sites to a user (non-destructive, preserves existing assignments):
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"sites": [
{
"slug": "site-1",
"permissions": ["view_site", "access_site"]
},
{
"slug": "site-2"
}
]
}'
Response (200 OK):
{
"success": true,
"data": {
"assigned_sites": 2
},
"message": "Successfully assigned 2 site(s) to user"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
json={
"sites": [
{
"slug": "site-1",
"permissions": ["view_site", "access_site"]
},
{
"slug": "site-2"
}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
sites: [
{
slug: "site-1",
permissions: ["view_site", "access_site"]
},
{
slug: "site-2"
}
]
})
})
const data = await response.json()
If permissions are not specified, view_site is assigned by default.
Valid Permissions:
view_site- View site informationaccess_site- Access site resourcesmanage_site- Manage site settingsmanage_site_users- Manage site user permissionsadmin_site- Full site administration
Replace All Sites for User
Replace all site assignments (atomic operation):
- REST API
- Python
- JavaScript
curl -X PUT https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"sites": [
{
"slug": "site-1",
"permissions": ["view_site"]
}
]
}'
Response (200 OK):
{
"success": true,
"data": {
"total_sites": 1
},
"message": "Successfully replaced site assignments (1 sites)"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.put(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
json={
"sites": [
{
"slug": "site-1",
"permissions": ["view_site"]
}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
sites: [
{
slug: "site-1",
permissions: ["view_site"]
}
]
})
})
const data = await response.json()
PUT replaces ALL existing site assignments. Use an empty array to remove all site permissions.
Remove Sites from User
Remove multiple sites from a user (batch operation):
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"sites": ["site-1", "site-2", "site-3"]
}'
Response (200 OK):
{
"success": true,
"message": "Removed 3 site(s) from user (6 permissions deleted)"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
json={"sites": ["site-1", "site-2", "site-3"]}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/", {
method: "DELETE",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ sites: ["site-1", "site-2", "site-3"] })
})
const data = await response.json()
Site → Users API
Manage user assignments for a specific site.
List Site's Users
Get all users with access to a site:
- REST API
- Python
- JavaScript
curl -X GET "https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/?search=john" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response (200 OK):
{
"success": true,
"data": [
{
"username": "john.doe",
"email": "[email protected]",
"name": "John Doe",
"permissions": ["view_site", "access_site", "manage_site"]
},
{
"username": "jane.smith",
"email": "[email protected]",
"name": "Jane Smith",
"permissions": ["view_site"]
}
],
"total": 2,
"message": "Site users retrieved successfully"
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/",
headers=headers,
params={"search": "john"}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/?search=john", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
Query Parameters:
search: Search by username, email, first name, or last name
Add Users to Site
Add multiple users to a site (non-destructive):
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"users": [
{
"username": "john.doe",
"permissions": ["view_site", "access_site"]
},
{
"username": "jane.smith"
}
]
}'
Response (200 OK):
{
"success": true,
"data": {
"assigned_users": 2
},
"message": "Successfully assigned 2 user(s) to site"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/",
headers=headers,
json={
"users": [
{
"username": "john.doe",
"permissions": ["view_site", "access_site"]
},
{
"username": "jane.smith"
}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
users: [
{
username: "john.doe",
permissions: ["view_site", "access_site"]
},
{
username: "jane.smith"
}
]
})
})
const data = await response.json()
Replace All Users for Site
Replace all user assignments (atomic operation):
- REST API
- Python
- JavaScript
curl -X PUT https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"users": [
{
"username": "john.doe",
"permissions": ["admin_site"]
}
]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.put(
"https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/",
headers=headers,
json={
"users": [
{
"username": "john.doe",
"permissions": ["admin_site"]
}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
users: [
{
username: "john.doe",
permissions: ["admin_site"]
}
]
})
})
const data = await response.json()
Remove Users from Site
Remove multiple users from a site:
- REST API
- Python
- JavaScript
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"users": ["john.doe", "jane.smith"]
}'
Response (200 OK):
{
"success": true,
"message": "Removed 2 user(s) from site (4 permissions deleted)"
}
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/",
headers=headers,
json={"users": ["john.doe", "jane.smith"]}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/production-site/users/", {
method: "DELETE",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ users: ["john.doe", "jane.smith"] })
})
const data = await response.json()
Permission Model
Who can manage user-site relationships:
- Superusers: Can manage any user's site assignments
- Organization Admins/Owners: Can manage user-site relationships within their organization
- Users with
manage_organizationpermission: Can manage relationships within their organization - Self-view: Users can view (but not modify) their own site assignments
Validation Rules:
- Sites must belong to the same organization as the user
- Users must be members of the organization that owns the site
- Self-modification is not allowed (users cannot modify their own site assignments)
- Cross-organization assignments are denied
Use Cases
Onboarding a New Team Member:
- REST API
- Python
- JavaScript
# Add user to organization first
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"user_id": "john.doe"}'
# Then assign site access
curl -X POST https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"sites": [
{"slug": "production", "permissions": ["view_site"]},
{"slug": "staging", "permissions": ["view_site", "access_site"]}
]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
# Add user to organization first
requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers,
json={"user_id": "john.doe"}
)
# Then assign site access
requests.post(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
json={
"sites": [
{"slug": "production", "permissions": ["view_site"]},
{"slug": "staging", "permissions": ["view_site", "access_site"]}
]
}
)
const headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
// Add user to organization first
await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
method: "POST",
headers,
body: JSON.stringify({ user_id: "john.doe" })
})
// Then assign site access
await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/", {
method: "POST",
headers,
body: JSON.stringify({
sites: [
{ slug: "production", permissions: ["view_site"] },
{ slug: "staging", permissions: ["view_site", "access_site"] }
]
})
})
Bulk User Assignment to New Site:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/sites/new-project/users/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"users": [
{"username": "john.doe", "permissions": ["admin_site"]},
{"username": "jane.smith", "permissions": ["view_site", "access_site"]},
{"username": "bob.johnson", "permissions": ["view_site"]}
]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/sites/new-project/users/",
headers=headers,
json={
"users": [
{"username": "john.doe", "permissions": ["admin_site"]},
{"username": "jane.smith", "permissions": ["view_site", "access_site"]},
{"username": "bob.johnson", "permissions": ["view_site"]}
]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/sites/new-project/users/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
users: [
{ username: "john.doe", permissions: ["admin_site"] },
{ username: "jane.smith", permissions: ["view_site", "access_site"] },
{ username: "bob.johnson", permissions: ["view_site"] }
]
})
})
const data = await response.json()
Role Change (Promotion to Site Admin):
- REST API
- Python
- JavaScript
# Replace existing permissions with admin
curl -X PUT https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"sites": [
{"slug": "production", "permissions": ["admin_site"]}
]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
# Replace existing permissions with admin
response = requests.put(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
json={
"sites": [
{"slug": "production", "permissions": ["admin_site"]}
]
}
)
data = response.json()
// Replace existing permissions with admin
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
sites: [
{ slug: "production", permissions: ["admin_site"] }
]
})
})
const data = await response.json()
Offboarding User:
- REST API
- Python
- JavaScript
# Remove all site access
curl -X DELETE https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"sites": ["production", "staging", "development"]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
# Remove all site access
response = requests.delete(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/",
headers=headers,
json={"sites": ["production", "staging", "development"]}
)
data = response.json()
// Remove all site access
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/sites/", {
method: "DELETE",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ sites: ["production", "staging", "development"] })
})
const data = await response.json()
Groups
Users can be assigned to groups for shared permissions:
Platform-Level Groups
- REST API
- Python
- JavaScript
# Get user with groups
curl -X GET https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response includes groups:
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"username": "john.doe",
"groups": [
{
"id": 1,
"name": "Developers"
}
]
}
import requests
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers
)
data = response.json()
groups = data.get("groups", [])
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
headers: { "Authorization": "Bearer YOUR_ACCESS_TOKEN" }
})
const data = await response.json()
const groups = data.groups
Organization-Level Groups
Assign users to organization-specific groups:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"user_id": "john.doe",
"group_ids": [1, 2]
}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/",
headers=headers,
json={
"user_id": "john.doe",
"group_ids": [1, 2]
}
)
data = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/organizations/acme-corp/members/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({
user_id: "john.doe",
group_ids: [1, 2]
})
})
const data = await response.json()
Authentication
JWT Authentication
Get access token:
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/ \
-H "Content-Type: application/json" \
-d '{"username": "john.doe", "password": "your-password"}'
Response:
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"user": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"username": "john.doe",
"email": "[email protected]"
}
}
Use in requests:
curl -X GET https://your-site.taruvi.cloud/api/cloud/users/john.doe/ \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc..."
import requests
# Get access token
auth_response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/",
json={"username": "john.doe", "password": "your-password"}
)
tokens = auth_response.json()
# Use in requests
headers = {"Authorization": f"Bearer {tokens['access']}"}
response = requests.get(
"https://your-site.taruvi.cloud/api/cloud/users/john.doe/",
headers=headers
)
data = response.json()
// Get access token
const authResponse = await fetch("https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username: "john.doe", password: "your-password" })
})
const tokens = await authResponse.json()
// Use in requests
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/users/john.doe/", {
headers: { "Authorization": `Bearer ${tokens.access}` }
})
const data = await response.json()
Refresh Token
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."}'
import requests
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/refresh/",
json={"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."}
)
new_tokens = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/refresh/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ refresh: "eyJ0eXAiOiJKV1QiLCJhbGc..." })
})
const newTokens = await response.json()
Verify Token
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/verify/ \
-H "Content-Type: application/json" \
-d '{"token": "eyJ0eXAiOiJKV1QiLCJhbGc..."}'
import requests
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/verify/",
json={"token": "eyJ0eXAiOiJKV1QiLCJhbGc..."}
)
result = response.json()
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/verify/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: "eyJ0eXAiOiJKV1QiLCJhbGc..." })
})
const result = await response.json()
Logout (Blacklist Token)
- REST API
- Python
- JavaScript
curl -X POST https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/blacklist/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."}'
import requests
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/blacklist/",
headers=headers,
json={"refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."}
)
const response = await fetch("https://your-site.taruvi.cloud/api/cloud/auth/jwt/token/blacklist/", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify({ refresh: "eyJ0eXAiOiJKV1QiLCJhbGc..." })
})
OAuth/Social Authentication
Taruvi supports OAuth authentication with various providers:
- Google OAuth
- GitHub OAuth
- Other social providers
See Social Authentication Documentation for setup and usage.
Permissions
User-level permissions:
| Permission | Description |
|---|---|
view_user | View user details |
add_user | Create new users |
change_user | Update user information |
delete_user | Delete users |
Users also inherit permissions from:
- Organization membership
- Group assignments
- Site-specific permissions
Best Practices
- Unique Usernames: Ensure usernames are unique and descriptive
- Strong Passwords: Enforce strong password policies
- Email Verification: Verify email addresses during signup
- Soft Deletes: Deactivate users instead of hard deleting
- Least Privilege: Grant minimum required permissions
- Regular Audits: Review user access and permissions regularly
- MFA: Implement multi-factor authentication for sensitive accounts
- Session Management: Set appropriate token expiration times
Security Considerations
- Password Storage: Passwords are hashed using Django's default hasher (PBKDF2)
- Token Expiration: JWT tokens have configurable expiration
- Rate Limiting: Login attempts are rate-limited
- Permission Checks: All operations check object-level permissions
- Audit Trail: User actions are logged for compliance
Common Workflows
User Registration Flow
- User submits registration form
- Create user account (inactive by default)
- Send verification email
- User clicks verification link
- Activate user account
- User can login
Organization Onboarding
- Create organization
- Send invitation to users
- Users accept invitation
- Assign users to groups
- Grant site-specific permissions
- Users can access organization resources
Password Reset
- User requests password reset
- System sends reset email
- User clicks reset link
- User sets new password
- Previous tokens are invalidated
Error Responses
User Not Found
{
"detail": "Not found.",
"code": "not_found",
"status_code": 404
}
Duplicate Username
{
"username": ["A user with that username already exists."],
"code": "unique_constraint",
"status_code": 400
}
Permission Denied
{
"detail": "You do not have permission to perform this action.",
"code": "permission_denied",
"status_code": 403
}
Invalid Credentials
{
"detail": "No active account found with the given credentials",
"code": "invalid_credentials",
"status_code": 401
}
Related Features
- User Management API - Complete API reference for user operations
- User Preferences - Manage user display and UI preferences
- Organizations - Manage user organization memberships
- Groups - Organize users with group-based permissions
- Permissions - Fine-grained access control
- Social Authentication - OAuth and social login setup
- Cloud Console API - Complete Cloud Console overview