broadfield-dev commited on
Commit
232f8b9
·
verified ·
1 Parent(s): 0cb08b4

Update gradio_keylock/component.py

Browse files
Files changed (1) hide show
  1. gradio_keylock/component.py +154 -27
gradio_keylock/component.py CHANGED
@@ -164,49 +164,176 @@ class AppServerLogic:
164
  return priv, pub
165
 
166
  class KeylockDecoderComponent:
167
- def __init__(self, server_logic: AppServerLogic):
168
  self.server_logic = server_logic
169
  self.image_input = None
170
  self.status_display = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
- def build_ui(self):
173
- with gr.Group():
174
- self.image_input = gr.Image(label="KeyLock Image", type="pil", show_label=False)
175
- self.status_display = gr.Markdown("Upload a KeyLock image to auto-fill credentials.")
176
- with gr.Accordion("Generate Encrypted Image", open=False):
177
- payload_input = gr.Textbox(
178
- label="Payload to Encrypt (Demo)",
179
- placeholder="USER = \"demo-user\"\nPASS: DEMO_test_PASS\n# Lines starting with # are ignored",
180
- lines=5,
181
- value="""
182
- USER = "TestUser"
183
- PASS: TestPass
184
- "GROQ_API_KEY" = "ALKSDFJASHFKSFH"
185
- "HF_API_KEY" : "SDFLSDJFFIEWOIFHOWI"
186
- "OPENAI_API_KEY" : SDFLSJDSFSDF
187
- """,
188
- )
189
- generate_img_button = gr.Button("Generate Image", variant="secondary")
190
- generated_image_preview = gr.Image(label="Generated Image Preview", type="filepath", interactive=False)
191
- generated_file_download = gr.File(label="Download Uncorrupted PNG", interactive=False)
192
- with gr.Accordion("Create New Standalone Key Pair", open=False):
193
- generate_keys_button = gr.Button("Generate Keys", variant="secondary")
194
- with gr.Row():
195
- output_private_key = gr.Code(label="Generated Private Key", language="python")
196
- output_public_key = gr.Code(label="Generated Public Key", language="python")
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  def generate_wrapper(kv_string):
199
  payload_dict = self.server_logic._parse_kv_string(kv_string)
200
  return self.server_logic.generate_encrypted_image(payload_dict)
201
 
 
 
 
 
 
 
202
  generate_img_button.click(
203
  fn=generate_wrapper,
204
  inputs=[payload_input],
205
  outputs=[generated_image_preview, generated_file_download]
206
  )
 
207
  generate_keys_button.click(
208
  fn=self.server_logic.generate_pem_keys,
209
  inputs=None,
210
  outputs=[output_private_key, output_public_key]
211
  )
212
- return self.image_input, self.status_display
 
 
164
  return priv, pub
165
 
166
  class KeylockDecoderComponent:
167
+ def __init__(self, server_logic):
168
  self.server_logic = server_logic
169
  self.image_input = None
170
  self.status_display = None
171
+
172
+ self.CSS = """
173
+ #login-container {
174
+ max-width: 480px;
175
+ margin: 4rem auto !important;
176
+ padding: 2rem 2.5rem;
177
+ background-color: rgba(22, 27, 34, 0.85);
178
+ border: 1px solid #30363d;
179
+ border-radius: 12px;
180
+ box-shadow: 0 8px 32px rgba(0,0,0,0.5);
181
+ }
182
+ #keylock-logo {
183
+ text-align: center;
184
+ font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
185
+ color: #c9d1d9;
186
+ margin-bottom: 1.5rem;
187
+ }
188
+ #keylock-logo svg {
189
+ width: 48px;
190
+ height: 48px;
191
+ fill: #58a6ff;
192
+ margin-bottom: 0.75rem;
193
+ }
194
+ #keylock-logo h1 {
195
+ font-size: 24px;
196
+ font-weight: 600;
197
+ margin: 0;
198
+ }
199
+ #image-upload-box {
200
+ background-color: #0d1117 !important;
201
+ border: 2px dashed #30363d !important;
202
+ border-radius: 8px !important;
203
+ min-height: 220px;
204
+ transition: border-color 0.2s ease-in-out, background-color 0.2s ease-in-out;
205
+ }
206
+ #image-upload-box:hover {
207
+ border-color: #58a6ff !important;
208
+ background-color: #161b22 !important;
209
+ }
210
+ #image-upload-box .!h-full.w-full > div:first-of-type {
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ color: #8b949e;
215
+ }
216
+ #status-display {
217
+ text-align: center;
218
+ padding: 1rem;
219
+ border-radius: 6px;
220
+ margin-top: 1rem;
221
+ min-height: 50px;
222
+ background-color: #161b22;
223
+ border: 1px solid #30363d;
224
+ transition: all 0.3s ease;
225
+ }
226
+ #status-display ul {
227
+ list-style-type: none;
228
+ padding: 0;
229
+ margin: 0.5rem 0 0 0;
230
+ text-align: left;
231
+ }
232
+ #status-display li {
233
+ background-color: #0d1117;
234
+ padding: 0.5rem;
235
+ margin-top: 0.5rem;
236
+ border-radius: 4px;
237
+ border: 1px solid #30363d;
238
+ }
239
+ .tool-accordion {
240
+ border-color: #30363d !important;
241
+ background-color: #0d1117 !important;
242
+ border-radius: 8px !important;
243
+ margin-top: 1.5rem;
244
+ }
245
+ .tool-accordion > .label-wrap {
246
+ background-color: #161b22 !important;
247
+ }
248
+ """
249
 
250
+ def _handle_login_attempt(self, image_input: Image.Image):
251
+ if image_input is None:
252
+ return gr.update(value='<p style="color:#8b949e;">Awaiting KeyLock image...</p>', visible=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
+ result = self.server_logic.decode_payload(image_input)
255
+
256
+ if result["status"] == "Success":
257
+ payload_html = "<ul>"
258
+ for key, value in result['payload'].items():
259
+ value_display = "•" * len(str(value)) if "pass" in key.lower() else value
260
+ payload_html += f"<li><strong>{key}:</strong> {value_display}</li>"
261
+ payload_html += "</ul>"
262
+
263
+ return gr.update(
264
+ value=f'<div style="color:#3fb950;">'
265
+ f'<h4>Authentication Success</h4>'
266
+ f'{payload_html}'
267
+ f'</div>',
268
+ visible=True
269
+ )
270
+ else:
271
+ return gr.update(
272
+ value=f'<p style="color:#f85149;"><strong>Login Failed:</strong> {result["message"]}</p>',
273
+ visible=True
274
+ )
275
+
276
+ def build_ui(self):
277
+ with gr.Column(elem_id="login-container"):
278
+ gr.HTML("""
279
+ <div id="keylock-logo">
280
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"></path></svg>
281
+ <h1>KeyLock Authentication</h1>
282
+ </div>
283
+ """)
284
+
285
+ self.image_input = gr.Image(
286
+ label="KeyLock Image",
287
+ type="pil",
288
+ show_label=False,
289
+ elem_id="image-upload-box"
290
+ )
291
+
292
+ self.status_display = gr.HTML(
293
+ '<p style="color:#8b949e;">Upload a KeyLock image to authenticate.</p>',
294
+ elem_id="status-display"
295
+ )
296
+
297
+ with gr.Accordion("Generator Tools", open=False, elem_classes=["tool-accordion"]):
298
+ with gr.Tabs():
299
+ with gr.TabItem("Encrypt Payload"):
300
+ payload_input = gr.Textbox(
301
+ label="Data to Encrypt (Key=Value format)",
302
+ placeholder="USER = \"demo-user\"\nPASS: DEMO_test_PASS\n# Lines starting with # are ignored",
303
+ lines=5,
304
+ value="""USER = "TestUser"\nPASS: TestPass\n"GROQ_API_KEY" = "ALKSDFJASHFKSFH" """,
305
+ )
306
+ generate_img_button = gr.Button("Generate Encrypted Image", variant="primary")
307
+ generated_image_preview = gr.Image(label="Generated Image Preview", type="filepath", interactive=False)
308
+ generated_file_download = gr.File(label="Download Uncorrupted PNG", interactive=False)
309
+
310
+ with gr.TabItem("Create Key Pair"):
311
+ gr.Markdown("Create a new standalone RSA-2048 key pair.")
312
+ generate_keys_button = gr.Button("Generate Keys", variant="secondary")
313
+ with gr.Row():
314
+ output_private_key = gr.Code(label="Generated Private Key", language="pem", interactive=False)
315
+ output_public_key = gr.Code(label="Generated Public Key", language="pem", interactive=False)
316
+
317
  def generate_wrapper(kv_string):
318
  payload_dict = self.server_logic._parse_kv_string(kv_string)
319
  return self.server_logic.generate_encrypted_image(payload_dict)
320
 
321
+ self.image_input.upload(
322
+ fn=self._handle_login_attempt,
323
+ inputs=[self.image_input],
324
+ outputs=[self.status_display]
325
+ )
326
+
327
  generate_img_button.click(
328
  fn=generate_wrapper,
329
  inputs=[payload_input],
330
  outputs=[generated_image_preview, generated_file_download]
331
  )
332
+
333
  generate_keys_button.click(
334
  fn=self.server_logic.generate_pem_keys,
335
  inputs=None,
336
  outputs=[output_private_key, output_public_key]
337
  )
338
+
339
+ return self.image_input, self.status_display