outmailauth 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- outmailauth-0.0.0/PKG-INFO +3 -0
- outmailauth-0.0.0/outmailauth/__init__.py +0 -0
- outmailauth-0.0.0/outmailauth/auth.py +144 -0
- outmailauth-0.0.0/outmailauth.egg-info/PKG-INFO +3 -0
- outmailauth-0.0.0/outmailauth.egg-info/SOURCES.txt +7 -0
- outmailauth-0.0.0/outmailauth.egg-info/dependency_links.txt +1 -0
- outmailauth-0.0.0/outmailauth.egg-info/top_level.txt +1 -0
- outmailauth-0.0.0/pyproject.toml +16 -0
- outmailauth-0.0.0/setup.cfg +4 -0
|
File without changes
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import base64
|
|
3
|
+
from flask import Flask, request, redirect
|
|
4
|
+
from google_auth_oauthlib.flow import Flow
|
|
5
|
+
from googleapiclient.discovery import build
|
|
6
|
+
import firebase_admin
|
|
7
|
+
from firebase_admin import credentials, db
|
|
8
|
+
|
|
9
|
+
PORT = 4000
|
|
10
|
+
REDIRECT_URI = f"http://localhost:{PORT}/oauth2callback"
|
|
11
|
+
|
|
12
|
+
SCOPES = [
|
|
13
|
+
"https://www.googleapis.com/auth/gmail.readonly",
|
|
14
|
+
"https://www.googleapis.com/auth/gmail.send"
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
CLIENT_CONFIG = {
|
|
18
|
+
"web": {
|
|
19
|
+
"client_id": "YOUR_CLIENT_ID",
|
|
20
|
+
"client_secret": "YOUR_CLIENT_SECRET",
|
|
21
|
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
22
|
+
"token_uri": "https://oauth2.googleapis.com/token",
|
|
23
|
+
"redirect_uris": [REDIRECT_URI]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Firebase initialization
|
|
28
|
+
cred = credentials.Certificate("serviceAccountKey.json")
|
|
29
|
+
firebase_admin.initialize_app(cred, {
|
|
30
|
+
"databaseURL": "https://utmail-17fba-default-rtdb.firebaseio.com/"
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
app = Flask(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def create_flow():
|
|
37
|
+
return Flow.from_client_config(
|
|
38
|
+
CLIENT_CONFIG,
|
|
39
|
+
scopes=SCOPES,
|
|
40
|
+
redirect_uri=REDIRECT_URI
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def check_api_key(key):
|
|
45
|
+
try:
|
|
46
|
+
ref = db.reference(key)
|
|
47
|
+
data = ref.get()
|
|
48
|
+
if data is None:
|
|
49
|
+
return False
|
|
50
|
+
return True
|
|
51
|
+
except:
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@app.route("/")
|
|
56
|
+
def home():
|
|
57
|
+
return """
|
|
58
|
+
<h2>0utmail Authentication</h2>
|
|
59
|
+
<form action="/auth">
|
|
60
|
+
<input name="key" placeholder="Enter API Key" required>
|
|
61
|
+
<button>Continue with Google</button>
|
|
62
|
+
</form>
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@app.route("/auth")
|
|
67
|
+
def auth():
|
|
68
|
+
key = request.args.get("key")
|
|
69
|
+
|
|
70
|
+
if not key:
|
|
71
|
+
return redirect("/")
|
|
72
|
+
|
|
73
|
+
if not check_api_key(key):
|
|
74
|
+
return "<h2>Invalid API key</h2>"
|
|
75
|
+
|
|
76
|
+
flow = create_flow()
|
|
77
|
+
|
|
78
|
+
state = base64.b64encode(json.dumps({"key": key}).encode()).decode()
|
|
79
|
+
|
|
80
|
+
auth_url, _ = flow.authorization_url(
|
|
81
|
+
access_type="offline",
|
|
82
|
+
prompt="consent",
|
|
83
|
+
state=state
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return redirect(auth_url)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@app.route("/oauth2callback")
|
|
90
|
+
def callback():
|
|
91
|
+
|
|
92
|
+
flow = create_flow()
|
|
93
|
+
|
|
94
|
+
flow.fetch_token(authorization_response=request.url)
|
|
95
|
+
|
|
96
|
+
creds = flow.credentials
|
|
97
|
+
|
|
98
|
+
tokens = {
|
|
99
|
+
"token": creds.token,
|
|
100
|
+
"refresh_token": creds.refresh_token,
|
|
101
|
+
"token_uri": creds.token_uri,
|
|
102
|
+
"client_id": creds.client_id
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
gmail = build("gmail", "v1", credentials=creds)
|
|
106
|
+
profile = gmail.users().getProfile(userId="me").execute()
|
|
107
|
+
|
|
108
|
+
email = profile["emailAddress"]
|
|
109
|
+
|
|
110
|
+
state = request.args.get("state")
|
|
111
|
+
|
|
112
|
+
api_key = None
|
|
113
|
+
if state:
|
|
114
|
+
try:
|
|
115
|
+
api_key = json.loads(base64.b64decode(state).decode())["key"]
|
|
116
|
+
except:
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
if api_key:
|
|
120
|
+
ref = db.reference(f"{api_key}/emails")
|
|
121
|
+
ref.push({
|
|
122
|
+
"email": email
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
return f"""
|
|
126
|
+
<h2>Credentials Generated</h2>
|
|
127
|
+
|
|
128
|
+
<h3>api-key.json</h3>
|
|
129
|
+
<pre>{json.dumps({'key': api_key}, indent=2)}</pre>
|
|
130
|
+
|
|
131
|
+
<h3>token.json</h3>
|
|
132
|
+
<pre>{json.dumps(tokens, indent=2)}</pre>
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
print(f"Server running on http://localhost:{PORT}")
|
|
138
|
+
app.run(port=PORT)
|
|
139
|
+
def main():
|
|
140
|
+
print(f"Server running on http://localhost:{PORT}")
|
|
141
|
+
app.run(port=PORT)
|
|
142
|
+
|
|
143
|
+
if __name__ == "__main__":
|
|
144
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
outmailauth
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[0utmaiauth]
|
|
2
|
+
name = "outmailauth"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "CLI tool to generate Gmail OAuth credentials for 0utmail"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
"flask",
|
|
10
|
+
"google-auth-oauthlib",
|
|
11
|
+
"google-api-python-client",
|
|
12
|
+
"firebase-admin"
|
|
13
|
+
]
|
|
14
|
+
[0utmailauth.scripts]
|
|
15
|
+
|
|
16
|
+
outmailauth = "outmailauth.auth:main"
|