Skip to content

Commit 34a799a

Browse files
Update NOTES.md, fix replication
1 parent 93877e8 commit 34a799a

File tree

6 files changed

+89
-84
lines changed

6 files changed

+89
-84
lines changed

NOTES.md

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,47 @@
11
# Terminology
2-
- Assset: this Django app, an asset refers to any resourthce or content that can be accessed and read via the internet. An asset is characterized by its accessibility through a unique link or identifier, allowing it to be easily retrieved or viewed by users of the app. The document can be viewed directly in the browser and/or using a client tool. Assets are highly versatile and can encompass a wide range of items, including but not limited to: Google Docs, web pages, Miro Diagrams, Google Slides, Microsoft Powerpoint slides.
2+
TODO: Make less passive and less verbose
3+
- Asset: any resource or content that can be accessed and read via the internet. An asset is characterized by its accessibility through a unique link or identifier, allowing it to be easily retrieved or viewed by users of the app. The asset can be viewed directly in the browser and/or using a client tool. Assets are highly versatile and can encompass a wide range of items, including but not limited to: Google Docs, web pages, Miro Diagrams, Google Slides, Microsoft Powerpoint slides.
34

45

56
# Knowledgebase App Overview
7+
68
The Knowledgebase App helps Hack for LA
7-
- maintain it's assets and related information. See data_values.md for details and examples for the catalog and categorization
9+
- maintain it's assets and related information. See [data_values.md](docs/design/data_values.md) for details and examples of topic areas, asset groups, and other related information.
810
- managing draft, in review, and completed versions of an asset
911
- filtering:
10-
- filter by assets based on related information
12+
- filter by assets based on related information such as topic area, asset groups, and other related information
1113
- identifying a primary asset in an asset group for purposes of filtering
1214
- Identifying a primary asset in a topic area for purposes of filtering
1315
- Google doc to web page conversion
1416
- Convert google doc to HTML
1517
- Add a section to the HTML that lists contributors and details
18+
- Manage authorization of Knowledgebase users
19+
20+
## Related information
1621

17-
**Related information**:
22+
For more details see [data_values.md](docs/design/data_values.md).
1823

1924
Related information that is maintained in the Knowledge base app:
2025
- topic area
2126
- asset group
2227
- asset category
2328
- asset type
2429

25-
Related information that is maintained in
30+
Related information that is maintained in People Depot:
2631
- practice area
2732
- technology
2833
- contributors
2934

30-
Other capability
31-
- Provide authorization to manage Knowledgebase users
32-
3335
# API Overview
34-
The API should allow for:
35-
- gettiing asset contributor, practice area, technology, topic area, asset type, asset category, and asset group
36-
- filtering assets by contributor, practice area, technology, topic area, asset type, asset category, and asset group
37-
- filtering by primary asset for an asset group
38-
- filtering by topic area for an asset group
39-
- getting the review status of a document
40-
- viewing a particular version (draft, in review, or approved) version of an asset
36+
37+
The API should let a user:
38+
- get a list of assets, contributors, practice areas, technologies, topic areas, asset types, asset categories, and asset groups
39+
- filter assets by contributor, practice area, technology, topic area, asset type, asset category, and asset group
40+
- filter an asset group by primary asset
41+
- filter an asset group by topic area
42+
- get the review status of a document
43+
44+
The API user must pick a version status - draft, in review, or approved - for any asset or assets they get. They can only get one version status at a time.
4145

4246

4347

@@ -46,43 +50,43 @@ The API should allow for:
4650
## Google Document Features
4751
# Technical Documentation
4852
# Technical Implementation
53+
4954
## People Depot Replication with SSO
50-
People Depot data is replicated when user logs in.
51-
### User Profile
52-
1. User attempts to login using kb url.
53-
2. If user is configured for SSO
54-
- user is redirected to login
55-
- user logs in
56-
- Cognito calls kb callback with parameters necessary to derive token using Cognito algorithm. Token is stored in variable.
57-
3. If user is not configured for SSO
58-
- user is drected to kb login page
59-
- user logs in using local account
60-
- token is derived using local algorithm. Token is stored in variable.
61-
4. /sync url is called. This is configured in LOGIN_REDIRECT_URL
62-
5. sync url triggers call to update_all_from_pd
63-
6. update_all_from_pd
64-
6.1 calls update_practice_area_from_pd
65-
- gets practice area data from https://<people depot server>/practice-areas w
66-
- data returned is used to create and update practice area records
67-
6.2 calls update_user_profile_from_pd
68-
- gets current user data from https://<people depot server>/profile with token in header
69-
- data returned is used to create or update information for current user
70-
6.3 calls update_users_from_pd
71-
- gets current user data from https://<people depot server>/users with token in header
72-
- data returned is used to create or update groups and users
73-
###
74-
1. User attempts to login using kb url.
75-
2. gets token from https://<people depot server>/login that passes entered user and password
76-
3.
77-
78-
## People Depot without SSO
79-
## Servers
80-
- Javascript service for converting a Google doc into a markdown and placed in a location to be picked up by Jekyll Hack for LA website.
81-
- Django app to implement the Knowledge Base Features
82-
- Interacts with Jekyll server
83-
- Interacts with People Depot
55+
56+
The Knowledgebase replicates the People Depot table when the user logs in. This is the log in flow:
57+
58+
1. User attempts to login using Knowledgebase url.
59+
2. For a normal user, we configure the Knowledgebase for SSO, therefore:
60+
2.1 user is redirected to Cognito login
61+
2.2 user logs in to Cognito
62+
TODO: 2.3 Cognito and Knowledgebase work together to create a token
63+
2.4 Knowledgebase calls People Depot /profile API to validate the user. If no such user exists,
64+
Knowledgebase shows an error screen.
65+
3. For an internal developers who is using Knowledgebase without SSO:
66+
3.1 user is directed to Knowledgebase login page
67+
3.2 user logs in with username and password
68+
3.3 Knowledgebase calls People Depot /login API to validate username and password against People Depot
69+
3.4 Knowledgebase creates a token
70+
5. Knowledgebase redirects the user to the /sync url. This is configured in the LOGIN_REDIRECT_URL environment variable.
71+
6. The view associated with the /sync url, `sync_view()`, calls `update_all_from_pd()`, which:
72+
6.1 calls `update_user_profile_from_pd()`, which:
73+
6.1.1 gets current user data from `https://<people depot server>/profile` with token in header
74+
6.1.2 creates or updates the user's record
75+
6.2 calls `update_users_from_pd()`
76+
6.2.1 gets current user data from `https://<people depot server>/users` with token in header
77+
6.2.2 creates or updates the records for the users and security groups
78+
6.3 calls `update_practice_area_from_pd()`
79+
6.3.1 gets practice area data from `https://<people depot server>/practice-areas` (without a token)
80+
6.3.2 creates or updates the practice area records
81+
82+
## Servers Knowledgebase interacts with
83+
84+
- Google doc conversion server. It converts a Google doc into markdown. We have written the backend for this server in javascript.
85+
- Jekyll server. The Jekyll server converts the markdown to HTML for the Hack for LA website.
86+
- People Depot API server
8487

8588
# User Documentation
89+
8690
What features needs to be covered:
8791
- List of supported Google Doc features
8892
- Security configuration

django_root/core/non_data_views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from django.core.handlers.wsgi import WSGIRequest
44
from people_depot.sync import update_all_from_pd
55

6-
def sync_view(__request__):
7-
update_all_from_pd()
6+
def sync_view(request):
7+
print("debug syncing")
8+
update_all_from_pd(request.user)
89
return redirect("/admin/")
910

1011

django_root/core/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@
4040
"secret": "",
4141
"key": "",
4242
},
43+
"SCOPE": ["openid", "profile", "email"], # Include 'openid' for the aud claim
4344
},
4445
}
46+
# print("Social account provider debug", SOCIALACCOUNT_PROVIDERS)
4547
ACCOUNT_EMAIL_VERIFICATION = "none"
4648
# Build paths inside the project like this: BASE_DIR / 'subdir'.
4749
BASE_DIR = Path(__file__).resolve().parent.parent

django_root/core/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
path("accounts/", include("allauth.urls")),
2424
path("kb/socialsignup/", social_signup_view),
2525
path("kb/token/", token_view),
26-
path("sync", sync_view),
26+
path("sync/", sync_view),
2727
re_path(r"^", include("kb.autocomplete_urls")),
2828
re_path(r"^", include("kb.api.api_urls")),
2929
re_path(r"^", include("people_depot.api.api_urls")),
Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import os
2-
import hashlib
3-
import hmac
4-
import time
5-
import os
2+
from allauth.socialaccount.models import SocialAccount
3+
64

75

86
PEOPLE_DEPOT_URL = os.environ.get("PEOPLE_DEPOT_URL", default="")
@@ -15,19 +13,11 @@
1513

1614
class HeaderUtil:
1715
@staticmethod
18-
def prepare_headers():
16+
def prepare_headers(requesting_user):
1917
if not PEOPLE_DEPOT_URL:
2018
return {}
21-
timestamp = str(int(time.time()))
22-
message = f"{timestamp}{PEOPLE_DEPOT_API_KEY}"
23-
24-
signature = hmac.new(
25-
PEOPLE_DEPOT_API_SECRET.encode("utf-8"),
26-
message.encode("utf-8"),
27-
hashlib.sha256,
28-
).hexdigest()
29-
return {
30-
"X-API-Key": PEOPLE_DEPOT_API_KEY,
31-
"X-API-Timestamp": timestamp,
32-
"X-API-Signature": signature,
33-
}
19+
account = SocialAccount.objects.get(user=requesting_user)
20+
print("social token", account.socialtoken_set.all().order_by("-expires_at"))
21+
token = account.socialtoken_set.all().order_by("-expires_at").first()
22+
print(f"debug token {token}", token)
23+
return {"Authorization": f"Bearer {token}"}

django_root/people_depot/sync.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,34 @@
22
import os
33
import requests
44
from urllib3.exceptions import MaxRetryError
5+
from data.people_depot.header import HeaderUtil
56

67
PEOPLE_DEPOT_URL = os.environ.get("PEOPLE_DEPOT_URL", default="")
78

8-
def update_all_from_pd():
9+
def update_all_from_pd(requesting_user):
10+
print("people depot url", PEOPLE_DEPOT_URL)
911
if not PEOPLE_DEPOT_URL:
1012
return
1113
update_groups_from_pd()
12-
# update_practice_areas_from_pd()
13-
# update_users_from_pd()
14+
update_practice_areas_from_pd()
15+
update_users_from_pd(requesting_user)
1416

1517
def update_groups_from_pd():
1618
people_depot_url = PEOPLE_DEPOT_URL
1719
if PEOPLE_DEPOT_URL and not PEOPLE_DEPOT_URL.endswith("/"):
1820
people_depot_url += "/"
21+
print("updating groups")
1922
url = people_depot_url + "api/v1/groups"
20-
print(f"Updating PracticeArea from {people_depot_url}")
23+
print(f"Updating groups from {people_depot_url}")
2124
response = try_get(url)
2225
data = response.decode()
26+
print("debug response", data)
2327
data = json.loads(data)
24-
original_count = PracticeArea.objects.count()
28+
original_count = Group.objects.count()
2529
for record in data:
2630
Group.objects.get_or_create(id=record["id"], name=record["name"])
27-
new_count = PracticeArea.objects.count()
28-
print(f"Added {new_count-original_count} practice area records")
31+
new_count = Group.objects.count()
32+
print(f"Added {new_count-original_count} group records")
2933

3034

3135
def update_practice_areas_from_pd():
@@ -44,9 +48,10 @@ def update_practice_areas_from_pd():
4448
print(f"Added {new_count-original_count} practice area records")
4549

4650

47-
def update_users_from_pd():
51+
def update_users_from_pd(requesting_user):
4852
print("Fetching users from People Depot", PEOPLE_DEPOT_URL)
49-
headers = HeaderUtil.prepare_headers()
53+
headers = HeaderUtil.prepare_headers(requesting_user)
54+
print("Here")
5055

5156
# set user_data to json from response
5257
url = f"{ PEOPLE_DEPOT_URL }/api/v1/users/app/kb"
@@ -55,6 +60,7 @@ def update_users_from_pd():
5560
user_data = json.loads(decodedText)
5661

5762
for user_record in user_data:
63+
print("Debug user record2", user_record)
5864
group_ids = user_record["groups"]
5965

6066
# remove keys not in User model and remove groups
@@ -81,10 +87,13 @@ def update_users_from_pd():
8187

8288

8389
def try_get(url, headers=None):
84-
print("Trying to get", PEOPLE_DEPOT_URL)
85-
data = None
90+
print("Trying to get", url, headers)
8691
try:
87-
data = requests.get(url, headers=headers).content
92+
response = requests.get(url, headers=headers)
93+
if response.status_code != 200:
94+
print(f"Error: Received status code {response.status_code} for URL {url}")
95+
response.raise_for_status() # Raise an exception for HTTP errors
96+
8897
except requests.exceptions.ConnectionError or MaxRetryError as e:
8998
message = str(e).split("\n", 1)[0]
9099
print(
@@ -93,11 +102,10 @@ def try_get(url, headers=None):
93102
message,
94103
)
95104
raise Exception("Unable to connect to People Depot")
96-
return data
105+
return response.content
97106

98107

99108

100109
# put imports here to avoid circular imports
101110
from people_depot.models import User, PracticeArea
102111
from django.contrib.auth.models import Group
103-
from data.people_depot.header import HeaderUtil

0 commit comments

Comments
 (0)