Commit 5d338939 authored by Koen van der Veen's avatar Koen van der Veen
Browse files

small update password auth

parent beb00416
Showing with 7 additions and 7 deletions
+7 -7
%% Cell type:code id:3314359a tags:
``` python
%load_ext autoreload
%autoreload 2
# default_exp plugin.authenticators.password
```
%% Cell type:code id:72fee2f9 tags:
``` python
# export
# hide
import abc
from time import sleep
from pathlib import Path
import pymemri
from pymemri.data.basic import read_file
from pymemri.cvu.utils import get_default_cvu
from pymemri.plugin.states import RUN_USER_ACTION_NEEDED, RUN_USER_ACTION_COMPLETED
from pymemri.data.schema import CVUStoredDefinition
import time
from time import sleep
from fastscript import call_parse
import getpass
from pymemri.pod.client import DEFAULT_POD_ADDRESS
from fastscript import Param
from pymemri.pod.utils import *
```
%% Cell type:markdown id:b6adc8b5 tags:
%% Cell type:markdown id:6848db5e tags:
# Password Authenticator
%% Cell type:code id:21778b28 tags:
``` python
# export
# hide
class PasswordAuthenticator:
DEFAULT_CVU = "password_auth.cvu"
MAX_LOGIN_ATTEMPTS = 3
SLEEP_INTERVAL = 1.0
MAX_POLL_TIME = 600
def __init__(self, client, pluginRun):
self.client = client
self.pluginRun = pluginRun
self.isTest = False
def authenticate(self, login_callback):
self.request_user_credentials()
login_success = False
for i in range(self.MAX_LOGIN_ATTEMPTS):
username, password = self.poll_credentials()
try:
login_callback(username, password)
login_success = True
break
except Exception as e:
print("Login failed, invalid credentials.")
if self.pluginRun.account:
attempts_remaining = self.MAX_LOGIN_ATTEMPTS - (i + 1)
account = self.pluginRun.account[0]
account.errorMessage = f"Reached max login attempts. {attempts_remaining} attempts remaining"
self.client.update_item(account)
if not login_success:
self.pluginRun.status = "error"
self.client.update_item(self.pluginRun)
if self.pluginRun.account:
account = self.pluginRun.account[0]
account.errorMessage = "Reached max login attempts."
self.client.update_item(account)
raise RuntimeError("Reached max login attempts.")
def request_user_credentials(self):
cvu = get_default_cvu(self.DEFAULT_CVU)
self.client.create(cvu)
self.pluginRun.add_edge("view", cvu)
self.client.create_edge(self.pluginRun.get_edges("view")[0])
self.pluginRun.status = RUN_USER_ACTION_NEEDED
self.client.update_item(self.pluginRun)
def poll_credentials(self):
start_time = time.time()
while True:
if time.time() - start_time > self.MAX_POLL_TIME:
self.pluginRun.status = "error"
self.client.update_item(self.pluginRun)
raise RuntimeError("Stop polling, max time reached.")
sleep(self.SLEEP_INTERVAL)
self.pluginRun = self.client.get(self.pluginRun.id)
print(f"polling for credentials... run.status={self.pluginRun.status}", flush=True)
print(f"polling for credentials from account of pluginRun {self.pluginRun.id} ... run.status={self.pluginRun.status}", flush=True)
if self.pluginRun.status == RUN_USER_ACTION_COMPLETED:
account = self.pluginRun.account[0]
return account.identifier, account.secret
```
%% Cell type:code id:a9af5c21 tags:
``` python
from pymemri.plugin.pluginbase import PluginBase
from pymemri.plugin.schema import PluginRun, Account
from pymemri.pod.client import PodClient
import threading
class MyAuthenticatedPlugin(PluginBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.logged_in = False
self.authenticator = PasswordAuthenticator(self.client, self.pluginRun)
def login(self, username, password):
if not (username=="username" and password=="password"):
raise ValueError("Wrong credentials.")
def run(self):
self.authenticator.authenticate(login_callback=self.login)
self.logged_in = True
print("done!")
def add_to_schema(self):
pass
```
%% Cell type:code id:fa71d04a tags:
%% Cell type:code id:dd6499a7 tags:
``` python
pod_client = PodClient()
run = PluginRun("", "", "")
account = Account(service="myAccount")
run.add_edge("account", account)
run.status = "started"
pod_client.create(run)
pod_client.create(account)
pod_client.create_edge(run.get_edges("account")[0]);
```
%% Cell type:markdown id:d785f671 tags:
%% Cell type:markdown id:b7d9b9fc tags:
# Simulate entering credentials
%% Cell type:code id:c6115e68 tags:
``` python
# export
def set_account_credentials(pod_client, run_id, username, password):
run = pod_client.get(run_id)
account = run.account[0]
account.identifier = username
account.secret = password
run.status = "ready"
pod_client.update_item(account)
pod_client.update_item(run)
print(f"Setting username and password for {run_id}'s Account'")
```
%% Cell type:code id:143111b0 tags:
%% Cell type:code id:12604f8b tags:
``` python
# export
from pymemri.pod.client import PodClient
@call_parse
def simulate_enter_credentials(run_id:Param("run id that requires the password", str),
pod_full_address:Param("The pod full address", str)=DEFAULT_POD_ADDRESS,
database_key:Param("Database key of the pod", str)=None,
owner_key:Param("Owner key of the pod", str)=None,):
if database_key is None: database_key = read_pod_key("database_key")
if owner_key is None: owner_key = read_pod_key("owner_key")
client = PodClient(url=pod_full_address, database_key=database_key, owner_key=owner_key)
username = input(f"Enter username for service used by {run_id}: ")
password = getpass.getpass(f"Enter password for service used by {run_id}: ")
set_account_credentials(client, run_id, username, password)
```
%% Cell type:code id:796deb89 tags:
``` python
# hide
# Create Plugin
plugin = MyAuthenticatedPlugin(client=pod_client, pluginRun=run)
thread = threading.Thread(target=plugin.run)
thread.start()
# Enter password and check if plugin is authenticated
sleep(0.5)
set_account_credentials(pod_client, run.id, "username", "password")
sleep(0.5)
thread.join()
assert plugin.logged_in
```
%% Output
Setting username and password for 6be33c3EdeabF2D0d53B873DcdeaCc09's Account'
polling for credentials... run.status=ready
done!
%% Cell type:markdown id:9334ddbc tags:
%% Cell type:markdown id:71affde0 tags:
# Export -
%% Cell type:code id:e1592e49 tags:
``` python
# hide
from nbdev.export import notebook2script
notebook2script()
```
%% Output
Converted basic.ipynb.
Converted cvu.utils.ipynb.
Converted data.photo.ipynb.
Converted importers.Importer.ipynb.
Converted importers.util.ipynb.
Converted index.ipynb.
Converted indexers.indexer.ipynb.
Converted itembase.ipynb.
Converted plugin.authenticators.oauth.ipynb.
Converted plugin.pluginbase.ipynb.
Converted plugin.schema.ipynb.
Converted plugin.states.ipynb.
Converted plugins.authenticators.password.ipynb.
Converted pod.client.ipynb.
Converted pod.db.ipynb.
Converted pod.utils.ipynb.
Converted test_utils.ipynb.
%% Cell type:code id:32203c8c tags:
``` python
```
......
......@@ -83,7 +83,7 @@ class PasswordAuthenticator:
sleep(self.SLEEP_INTERVAL)
self.pluginRun = self.client.get(self.pluginRun.id)
print(f"polling for credentials... run.status={self.pluginRun.status}", flush=True)
print(f"polling for credentials from account of pluginRun {self.pluginRun.id} ... run.status={self.pluginRun.status}", flush=True)
if self.pluginRun.status == RUN_USER_ACTION_COMPLETED:
account = self.pluginRun.account[0]
return account.identifier, account.secret
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment