Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

仕様変更等 #43

Merged
merged 19 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cc6e7ef
feat: env.exampleにWebhook URLを追加
hyouhyan Sep 9, 2024
f4ec0ad
feat: env変更に伴い、README.mdの変更を追加
hyouhyan Sep 9, 2024
ee3314d
docs: 読点の統一
hyouhyan Sep 9, 2024
c1e12d5
refactor: 使ってないライブラリ削除
hyouhyan Sep 9, 2024
67d8694
Merge pull request #36 from nanocom2024/webhook-log
k22036 Sep 9, 2024
aa8bfaa
fix: userがfirebaseに存在して,DBに存在しない場合の処理
k22036 Sep 10, 2024
7112faf
Merge pull request #37 from nanocom2024/fix-signin-pass
hyouhyan Sep 10, 2024
331cd46
update: docstring
k22036 Sep 10, 2024
49c919f
change: pairing-process
k22036 Sep 10, 2024
94e4ce1
Merge pull request #38 from nanocom2024/change-pairing-process
hyouhyan Sep 10, 2024
bc4cadc
fix: signupの検証を少し厳しく
k22036 Sep 12, 2024
9ed3ec0
Merge pull request #39 from nanocom2024/fix-signup-double-create
hyouhyan Sep 12, 2024
9a1b6ca
fix: public_keyのmajorとminorを文字列として返すよう修正
k22036 Sep 13, 2024
8c09a86
Merge pull request #41 from nanocom2024/change-major-minor-to-str
hyouhyan Sep 13, 2024
d138bb2
add: 自身のデバイスを識別する
k22036 Sep 14, 2024
2c64c17
fix: auth_checkで無効なトークンに対するレスポンスコードを401に変更
k22036 Sep 14, 2024
aaf0226
change: auth_checkで未認証の場合,401を返すように変更
k22036 Sep 14, 2024
99c7383
change: すれ違いの認証情報としてtokenを利用するように変更
k22036 Sep 15, 2024
6e6ee71
Merge pull request #42 from nanocom2024/add-received-beacon-own
hyouhyan Sep 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion server/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
PATH_TO_FIREBASE_JSON = "example"
JWT_SECRET_KEY = "example"
FIREBASE_API_KEY = "example"
FIREBASE_API_KEY = "example"
LOG_WEBHOOK_URL = "https://discord.com/api/webhooks/1234567890/EXAMPLE"
11 changes: 6 additions & 5 deletions server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ FirebaseのAuthenticationを用いています
PATH_TO_FIREBASE_JSON = "example"
JWT_SECRET_KEY = "example"
FIREBASE_API_KEY = "example"
LOG_WEBHOOK_URL = "https://discord.com/api/webhooks/EXAMPLE"
```

Firebase Authenticationに従ってsdkのjsonを配置して,パスを設定してください

・serverの秘密鍵の設定もしてください

・firebaseのAPIキーも設定してください
- Firebase Authenticationに従ってsdkのjsonを配置して,パスを設定してください
- serverの秘密鍵の設定もしてください
- firebaseのAPIキーも設定してください
- ログをdiscordに送信する場合はwebhookのURLを設定してください
- 指定なしの場合,Webhook機能は自動的に無効になります

### ライブラリのインストール

Expand Down
1 change: 1 addition & 0 deletions server/src/Auth/firebase.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
def sign_in_with_email_and_password(api_key, email, password):
"""
Firebaseで認証を行う(SDKの signInWithEmailAndPassword と同値)
:param api_key:
:param email:
:param password:
Expand Down
12 changes: 8 additions & 4 deletions server/src/Auth/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ def signup():
if not password:
return jsonify({'error': 'Missing password'}), 400

if users.find_one({'email': email}):
return jsonify({'error': 'The user with the provided email already exists (EMAIL_EXISTS).'}), 400

try:
user = auth.create_user(email=email, password=password)
access_token = create_access_token(identity=user.uid)
except Exception as e:
return jsonify({'error': str(e)}), 400

if users.find_one({'email': email}):
users.delete_many({'email': email})

user = {
'uid': user.uid,
'name': name,
Expand Down Expand Up @@ -74,7 +74,11 @@ def signin():
if 'error' in res:
return jsonify({'error': res['error']['message']}), 400

users.update_one({'email': email}, {'$set': {'token': res['idToken']}})
if not users.find({'email': email}):
# firebaseにuserが存在するが、DBには存在しない場合
return jsonify({'error': 'User not found'}), 400
else:
users.update_one({'email': email}, {'$set': {'token': res['idToken']}})

return jsonify({'token': res['idToken']}), 200

Expand Down
44 changes: 44 additions & 0 deletions server/src/Pairing/PairingModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import hashlib
from DB import DB

db = DB()
device_keys = db.device_keys


def generate_major_minor(public_key):
"""
majorとminorをpublic_keyから生成する

:param public_key: str
:return major, minor: (str, str)
"""

temp = public_key
while True:
major, minor = generate(temp)
device_key = device_keys.find_one({'major': major, 'minor': minor})
if not device_key:
break
temp = hashlib.sha256(temp.encode()).hexdigest()

return str(major), str(minor)


def generate(key):
forward = key[:32]
backward = key[32:]

forward_hash = hashlib.sha256(forward.encode()).hexdigest()
backward_hash = hashlib.sha256(backward.encode()).hexdigest()

# 16bitのuintに変換
major = int(forward_hash, 16) % 2**16
minor = int(backward_hash, 16) % 2**16

return major, minor


if __name__ == '__main__':
public_key = 'a' * 64
print(generate(public_key))
# (42311, 42311)
37 changes: 26 additions & 11 deletions server/src/Pairing/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from flask import Blueprint, request, jsonify
from DB import DB
from crypto.generate import generate_ed25519_keypair
from Pairing import PairingModel
from flask_jwt_extended import create_access_token

PAIRING_BP = Blueprint('pairing', __name__, url_prefix='/pairing')
Expand All @@ -13,8 +14,8 @@
pairings = db.pairings


@PAIRING_BP.route('/generate_device_key', methods=['POST'])
def generate_device_key():
@PAIRING_BP.route('/generate_major_minor', methods=['POST'])
def generate_major_minor():
uid = request.json['uid']
if not uid:
return jsonify({'error': 'Missing uid'}), 400
Expand All @@ -24,40 +25,54 @@ def generate_device_key():

private_key, public_key = generate_ed25519_keypair()

major, minor = PairingModel.generate_major_minor(public_key)

device_keys.insert_one({
'uid': uid,
'private_key': private_key,
'public_key': public_key
'public_key': public_key,
'major': major,
'minor': minor
})

return jsonify({'private_key': private_key, 'public_key': public_key}), 200
return jsonify({
'private_key': private_key,
'public_key': public_key,
'major': major,
'minor': minor
}), 200


@PAIRING_BP.route('/register_pairing', methods=['POST'])
def register_pairing():
token = request.json['token']
if not token:
return jsonify({'error': 'Missing token'}), 400
public_key = request.json['public_key']
if not public_key:
return jsonify({'error': 'Missing public_key'}), 400
major = request.json['major']
if not major:
return jsonify({'error': 'Missing major'}), 400
minor = request.json['minor']
if not minor:
return jsonify({'error': 'Missing minor'}), 400

user = users.find_one({'token': token})
if not user:
return jsonify({'error': 'Invalid token'}), 400

device_key = device_keys.find_one({'public_key': public_key})
device_key = device_keys.find_one({'major': major, 'minor': minor})
if not device_key:
return jsonify({'error': 'Invalid public_key'}), 400
return jsonify({'error': 'Invalid major,minor'}), 400

pairings.delete_many({'uid': user['uid']})
pairings.delete_many({'public_key': device_key['public_key']})
pairings.delete_many({'private_key': device_key['private_key']})

pairings.insert_one({
'uid': user['uid'],
'private_key': device_key['private_key'],
'public_key': device_key['public_key'],
'private_key': device_key['private_key']
'major': major,
'minor': minor
})

return jsonify({'done': 'pairing'}), 200
Expand All @@ -71,7 +86,7 @@ def auth_check():

user = users.find_one({'token': token})
if not user:
return jsonify({'error': 'Invalid token'}), 400
return jsonify({'error': 'Invalid token'}), 401

new_token = create_access_token(identity=user['token'])
users.update_one({'token': token}, {'$set': {'token': new_token}})
Expand Down
30 changes: 19 additions & 11 deletions server/src/StreetPass/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# MongoDBに接続
db = DB()
users = db.users
pairings = db.pairings
pre_passes = db.pre_passes
now_passes = db.now_passes
Expand All @@ -15,19 +16,26 @@

@STREETPASS_BP.route('/received_beacon', methods=['POST'])
def received_beacon():
received_public_key = request.json['received_public_key']
if not received_public_key:
return jsonify({'error': 'Missing received_public_key'}), 400
private_key = request.json['private_key']
if not private_key:
return jsonify({'error': 'Missing private_key'}), 400

received_user = pairings.find_one({'public_key': received_public_key})
received_major = request.json['received_major']
if not received_major:
return jsonify({'error': 'Missing received_major'}), 400
received_minor = request.json['received_minor']
if not received_minor:
return jsonify({'error': 'Missing received_minor'}), 400
token = request.json['token']
if not token:
return jsonify({'error': 'Missing token'}), 400

received_user = pairings.find_one(
{'major': received_major, 'minor': received_minor})
if not received_user:
return jsonify({'error': 'Invalid received_public_key'}), 400
sent_user = pairings.find_one({'private_key': private_key})
return jsonify({'error': 'Invalid received_major_minor'}), 400
sent_user = users.find_one({'token': token})
if not sent_user:
return jsonify({'error': 'Invalid private_key'}), 400
return jsonify({'error': 'Invalid token'}), 400

if received_user['uid'] == sent_user['uid']:
return jsonify({'pass': 'own'}), 200

threshold = datetime.datetime.now() - datetime.timedelta(seconds=30)
pre_passes.delete_many({'created_at': {'$lt': threshold}})
Expand Down
17 changes: 17 additions & 0 deletions server/src/init_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from firebase_admin import auth
from DB import DB

db = DB()
users = db.users


def db_init():
# ユーザーがDBに存在して,Firebaseに存在しない場合はDBから削除
firebase_users = auth.list_users()
db_users = users.find()

firebase_uids = [user.uid for user in firebase_users.users]

for db_user in db_users:
if db_user['uid'] not in firebase_uids:
users.delete_one({'uid': db_user['uid']})
11 changes: 6 additions & 5 deletions server/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from Pairing.routes import PAIRING_BP
from StreetPass.routes import STREETPASS_BP
from Notification.routes import NOTIFICATION_BP
import init_server

import logging
import logging.handlers
from handlers import DiscordHandler


Expand All @@ -32,26 +32,27 @@
# jwt manager
jwt = JWTManager(app)

# init server
init_server.db_init()

# Blueprint
app.register_blueprint(AUTH_BP)
app.register_blueprint(PAIRING_BP)
app.register_blueprint(STREETPASS_BP)
app.register_blueprint(NOTIFICATION_BP)

webhook_url=settings.log_webhook_url
webhook_url = settings.log_webhook_url

# Discord Handler の作成
if(webhook_url):
if (webhook_url):
discord_handler = DiscordHandler(webhook_url)
discord_handler.setLevel(logging.INFO)
werkzeug_logger = logging.getLogger('werkzeug')
werkzeug_logger.addHandler(discord_handler)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
werkzeug_logger.addHandler(console_handler)



if __name__ == '__main__':
Expand Down
Loading