Chris Addis commited on
Commit
13dc13f
·
1 Parent(s): 33dac38
Files changed (1) hide show
  1. app.py +106 -15
app.py CHANGED
@@ -1,4 +1,3 @@
1
- # --- Application Logic ---
2
  import gradio as gr
3
  import os
4
  from huggingface_hub import HfApi, hf_hub_url
@@ -7,30 +6,92 @@ import json
7
  # IMPORTANT: This secret should be set in the Hugging Face Space settings, NOT hardcoded here.
8
  # We retrieve it using os.environ.get() which accesses the Space's environment variables/secrets.
9
  # Provide a default empty string for local testing where the secret won't exist.
10
- authorized_users_str = os.environ.get("AUTHORIZED_USER_IDS")
11
- AUTHORIZED_USER_IDS = set(authorized_users_str.split(','))
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  # Function to determine if the current user has full access
14
  def check_user_access():
15
  """Check if the current user has full access based on their Hugging Face identity."""
16
  try:
17
- # In Hugging Face Spaces, user information is available in environment variables
18
- # SPACE_ID contains the space name (e.g., username/space-name)
19
- # USER contains the logged-in username when using the space
20
- username = os.environ.get("USER")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
 
 
 
 
 
 
 
 
 
22
  # If still no username, user is not logged in
23
  if not username:
 
24
  return False, None
25
 
26
  # Check if user is in the authorized list
27
- has_full_access = username in AUTHORIZED_USER_ID
 
28
 
29
  return has_full_access, username
30
  except Exception as e:
31
  print(f"Error checking user access: {e}")
32
  return False, None
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  # Example data processing function (limited functionality)
35
  def process_data_limited(input_text):
36
  """Process data with limited functionality."""
@@ -63,6 +124,14 @@ def handle_submission(input_text):
63
  limited_user_display = f"Limited access for {username}" if username else "Limited access (not logged in)"
64
  return process_data_limited(input_text), limited_user_display, False
65
 
 
 
 
 
 
 
 
 
66
  # Create the Gradio interface
67
  with gr.Blocks(title="Access Control Demo") as demo:
68
  gr.Markdown("# Hugging Face Spaces Access Control Demo")
@@ -75,24 +144,25 @@ with gr.Blocks(title="Access Control Demo") as demo:
75
  To test different access levels, log in with different Hugging Face accounts.
76
  """)
77
 
78
- # Get initial access status
79
- has_full_access, username = check_user_access()
80
-
81
  # Display current user and access level
82
  with gr.Row():
83
  status_display = gr.Textbox(
84
- value=f"Full access for {username}" if has_full_access else
85
- f"Limited access for {username}" if username else
86
- "Limited access (not logged in)",
87
  label="Current Access Status",
88
  interactive=False
89
  )
90
  access_indicator = gr.Checkbox(
91
- value=has_full_access,
92
  label="Full Access",
93
  interactive=False
94
  )
95
 
 
 
 
 
 
 
 
 
96
  # Input form
97
  with gr.Row():
98
  input_text = gr.Textbox(
@@ -117,6 +187,27 @@ with gr.Blocks(title="Access Control Demo") as demo:
117
  outputs=[output_text, status_display, access_indicator]
118
  )
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  # Additional information section
121
  gr.Markdown("""
122
  ## How This Works
 
 
1
  import gradio as gr
2
  import os
3
  from huggingface_hub import HfApi, hf_hub_url
 
6
  # IMPORTANT: This secret should be set in the Hugging Face Space settings, NOT hardcoded here.
7
  # We retrieve it using os.environ.get() which accesses the Space's environment variables/secrets.
8
  # Provide a default empty string for local testing where the secret won't exist.
9
+ authorized_users_str = os.environ.get("AUTHORIZED_USER_IDS", "")
10
+ AUTHORIZED_USER_IDS = set(authorized_users_str.split(',') if authorized_users_str else [])
11
+
12
+ # Add a fallback list for development or if environment variable isn't set
13
+ if not AUTHORIZED_USER_IDS:
14
+ print("Warning: No authorized users found in environment variables.")
15
+ print("Using fallback authorized users list for development.")
16
+ # Fallback list - only used if AUTHORIZED_USER_IDS environment variable isn't set
17
+ AUTHORIZED_USER_IDS = set([
18
+ "authorized_user1",
19
+ "authorized_user2",
20
+ "your_username_here"
21
+ ])
22
+
23
+ print(f"Current authorized users: {AUTHORIZED_USER_IDS}")
24
 
25
  # Function to determine if the current user has full access
26
  def check_user_access():
27
  """Check if the current user has full access based on their Hugging Face identity."""
28
  try:
29
+ # Get username from Gradio's authentication context
30
+ # In Hugging Face Spaces, this will provide the logged-in username
31
+ username = None
32
+
33
+ # First, check if we're running in a Hugging Face Space
34
+ if hasattr(gr, "me") and callable(gr.me):
35
+ try:
36
+ # gr.me() returns user information when authenticated in Spaces
37
+ user_info = gr.me()
38
+ if user_info:
39
+ username = user_info.get("username")
40
+ print(f"Detected username via gr.me(): {username}")
41
+ except Exception as e:
42
+ print(f"Error using gr.me(): {e}")
43
+
44
+ # Fallback methods to get username
45
+ if not username:
46
+ # Try USER environment variable (as mentioned in your code)
47
+ username = os.environ.get("USER")
48
+ if username:
49
+ print(f"Using USER env var: {username}")
50
+
51
+ # Try SPACE_AUTHOR (might contain space owner's username)
52
+ if not username:
53
+ space_author = os.environ.get("SPACE_AUTHOR")
54
+ if space_author:
55
+ username = space_author
56
+ print(f"Using SPACE_AUTHOR: {username}")
57
 
58
+ # For local development/testing, you can set a mock username
59
+ if not username and os.environ.get("DEVELOPMENT_MODE"):
60
+ username = os.environ.get("MOCK_USERNAME", "test_user")
61
+ print(f"Using mock username: {username}")
62
+
63
+ # Debug output
64
+ print(f"Detected username: {username}")
65
+ print(f"Authorized users: {AUTHORIZED_USER_IDS}")
66
+
67
  # If still no username, user is not logged in
68
  if not username:
69
+ print("No username detected, assuming not logged in")
70
  return False, None
71
 
72
  # Check if user is in the authorized list
73
+ has_full_access = username in AUTHORIZED_USER_IDS
74
+ print(f"Full access granted: {has_full_access}")
75
 
76
  return has_full_access, username
77
  except Exception as e:
78
  print(f"Error checking user access: {e}")
79
  return False, None
80
 
81
+ # Function to add the current user to the authorized list (admin function)
82
+ def add_current_user_to_authorized():
83
+ _, username = check_user_access()
84
+ if not username:
85
+ return "Not logged in - can't add user", False
86
+
87
+ global AUTHORIZED_USER_IDS
88
+ if username not in AUTHORIZED_USER_IDS:
89
+ AUTHORIZED_USER_IDS.add(username)
90
+ print(f"Added {username} to authorized users. New list: {AUTHORIZED_USER_IDS}")
91
+ return f"Added {username} to authorized users!", True
92
+ else:
93
+ return f"{username} is already an authorized user", True
94
+
95
  # Example data processing function (limited functionality)
96
  def process_data_limited(input_text):
97
  """Process data with limited functionality."""
 
124
  limited_user_display = f"Limited access for {username}" if username else "Limited access (not logged in)"
125
  return process_data_limited(input_text), limited_user_display, False
126
 
127
+ # Function to get the current login status display
128
+ def get_login_status():
129
+ has_full_access, username = check_user_access()
130
+ status_text = f"Full access for {username}" if has_full_access else \
131
+ f"Limited access for {username}" if username else \
132
+ "Limited access (not logged in)"
133
+ return status_text, has_full_access
134
+
135
  # Create the Gradio interface
136
  with gr.Blocks(title="Access Control Demo") as demo:
137
  gr.Markdown("# Hugging Face Spaces Access Control Demo")
 
144
  To test different access levels, log in with different Hugging Face accounts.
145
  """)
146
 
 
 
 
147
  # Display current user and access level
148
  with gr.Row():
149
  status_display = gr.Textbox(
 
 
 
150
  label="Current Access Status",
151
  interactive=False
152
  )
153
  access_indicator = gr.Checkbox(
 
154
  label="Full Access",
155
  interactive=False
156
  )
157
 
158
+ # Add buttons for login management
159
+ with gr.Row():
160
+ refresh_btn = gr.Button("Refresh Login Status")
161
+ admin_btn = gr.Button("Add Me To Authorized Users")
162
+
163
+ # Output for admin actions
164
+ admin_result = gr.Textbox(label="Admin Action Result", interactive=False)
165
+
166
  # Input form
167
  with gr.Row():
168
  input_text = gr.Textbox(
 
187
  outputs=[output_text, status_display, access_indicator]
188
  )
189
 
190
+ # Connect the refresh button to update login status
191
+ refresh_btn.click(
192
+ fn=get_login_status,
193
+ inputs=[],
194
+ outputs=[status_display, access_indicator]
195
+ )
196
+
197
+ # Connect the admin button to add the current user to authorized users
198
+ admin_btn.click(
199
+ fn=add_current_user_to_authorized,
200
+ inputs=[],
201
+ outputs=[admin_result, access_indicator]
202
+ )
203
+
204
+ # Initialize the status display
205
+ demo.load(
206
+ fn=get_login_status,
207
+ inputs=[],
208
+ outputs=[status_display, access_indicator]
209
+ )
210
+
211
  # Additional information section
212
  gr.Markdown("""
213
  ## How This Works