Просмотр исходного кода

2차 비밀번호 기능 도입

잉여개발기 (SPDV) 5 лет назад
Родитель
Сommit
a136828f46
9 измененных файлов с 146 добавлено и 27 удалено
  1. 4 0
      app.py
  2. 4 0
      language/en-US.json
  3. 5 1
      language/ko-KR.json
  4. 27 14
      route/login.py
  5. 73 0
      route/login_2fa.py
  6. 1 1
      route/login_check_key.py
  7. 0 1
      route/login_register.py
  8. 1 1
      route/tool/set_mark/tool.py
  9. 31 9
      route/user_setting.py

+ 4 - 0
app.py

@@ -514,6 +514,10 @@ def topic_close_list(name = 'test'):
 def user_tool(name = None):
     return user_tool_2(conn, name)
 
+@app.route('/2fa_login', methods=['POST', 'GET'])
+def login_2fa():
+    return login_2fa_2(conn)
+
 @app.route('/login', methods=['POST', 'GET'])
 def login():
     return login_2(conn)

+ 4 - 0
language/en-US.json

@@ -96,6 +96,7 @@
         "icon" : "Icon",
         "view" : "View",
         "content" : "Content",
+        "on" : "On",
         "off" : "Off",
         "unset" : "Unset",
         "extension" : "Extension",
@@ -210,6 +211,9 @@
         "get_sitemap" : "Create or renewal sitemap.xml",
         "simple_check" : "Simple check",
         "add_user" : "Add user",
+        "2fa" : "2FA",
+        "2fa_password" : "2FA password",
+        "2fa_password_change" : "Change 2FA password",
         "_comment_2.1_" : "Filter",
             "_comment_2.1.1_" : "List",
                 "interwiki_list" : "Interwiki(s) list",

+ 5 - 1
language/ko-KR.json

@@ -388,5 +388,9 @@
     "1_line_1_q": "1줄당 1개의 선택지를 쓰세요.",
     "open_vote_list" : "열린 투표 목록",
     "close_vote" : "투표 닫기",
-    "re_open_vote" : "투표 다시 열기"
+    "re_open_vote" : "투표 다시 열기",
+    "on" : "켜기",
+    "2fa" : "2차 인증",
+    "2fa_password" : "2차 비밀번호",
+    "2fa_password_change" : "2차 비밀번호 변경"
 }

+ 27 - 14
route/login.py

@@ -17,8 +17,9 @@ def login_2(conn):
             captcha_post('', 0)
 
         agent = flask.request.headers.get('User-Agent')
+        user_id = flask.request.form.get('id', '')
 
-        curs.execute(db_change("select pw, encode from user where id = ?"), [flask.request.form.get('id', None)])
+        curs.execute(db_change("select pw, encode from user where id = ?"), [user_id])
         user = curs.fetchall()
         if not user:
             return re_error('/error/2')
@@ -27,28 +28,40 @@ def login_2(conn):
             flask.request.form.get('pw', ''),
             user[0][0],
             user[0][1],
-            flask.request.form.get('id', None)
+            user_id
         )
         if pw_check_d != 1:
             return re_error('/error/10')
 
-        flask.session['state'] = 1
-        flask.session['id'] = flask.request.form.get('id', None)
+        curs.execute(db_change('select data from user_set where name = "2fa" and id = ?'), [user_id])
+        fa_data_pw = curs.fetchall()
+        if fa_data_pw:
+            curs.execute(db_change("select css from custom where user = ?"), [user_id])
+            css_data = curs.fetchall()
+            flask.session['b_head'] = css_data[0][0] if css_data else ''
+            flask.session['b_id'] = user_id
 
-        curs.execute(db_change("select css from custom where user = ?"), [flask.request.form.get('id', None)])
-        css_data = curs.fetchall()
-        if css_data:
-            flask.session['head'] = css_data[0][0]
+            return redirect('/2fa_login')
         else:
-            flask.session['head'] = ''
+            curs.execute(db_change("select css from custom where user = ?"), [user_id])
+            css_data = curs.fetchall()
+            flask.session['head'] = css_data[0][0] if css_data else ''
+            flask.session['id'] = user_id
 
-        curs.execute(db_change("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')"), [flask.request.form.get('id', None), ip_check(1), agent, get_time()])
+            curs.execute(db_change("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')"), [
+                user_id, 
+                ip, 
+                agent, 
+                get_time()
+            ])
+            conn.commit()
 
-        conn.commit()
-
-        return redirect('/user')
+            return redirect('/user')
     else:
-        http_warring = '<hr class=\"main_hr\"><span>' + load_lang('http_warring') + '</span>'
+        http_warring = '' + \
+            '<hr class="main_hr">' + \
+            '<span>' + load_lang('http_warring') + '</span>' + \
+        ''
 
         return easy_minify(flask.render_template(skin_check(),
             imp = [load_lang('login'), wiki_set(), custom(), other2([0, 0])],

+ 73 - 0
route/login_2fa.py

@@ -0,0 +1,73 @@
+from .tool.func import *
+
+def login_2fa_2(conn):
+    curs = conn.cursor()
+
+    if not (flask.session and 'b_id' in flask.session):
+        return redirect('/user')
+
+    ip = ip_check()
+    if ip_or_user(ip) == 0:
+        return redirect('/user')
+
+    if ban_check(tool = 'login') == 1:
+        return re_error('/ban')
+
+    if flask.request.method == 'POST':
+        if captcha_post(flask.request.form.get('g-recaptcha-response', flask.request.form.get('g-recaptcha', ''))) == 1:
+            return re_error('/error/13')
+        else:
+            captcha_post('', 0)
+
+        agent = flask.request.headers.get('User-Agent')
+        user_id = flask.session['b_id']
+
+        curs.execute(db_change('select data from user_set where name = "2fa_pw" and id = ?'), [user_id])
+        user_1 = curs.fetchall()[0][0]
+
+        curs.execute(db_change('select data from user_set where name = "2fa_pw_encode" and id = ?'), [user_id])
+        user_2 = curs.fetchall()[0][0]
+
+        pw_check_d = pw_check(
+            flask.request.form.get('pw', ''),
+            user_1,
+            user_2,
+            user_id
+        )
+        if pw_check_d != 1:
+            return re_error('/error/10')
+
+        flask.session['head'] = flask.session['b_head']
+        flask.session['id'] = user_id
+
+        curs.execute(db_change("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')"), [
+            user_id, 
+            ip, 
+            agent, 
+            get_time()
+        ])
+        conn.commit()
+
+        flask.session.pop('b_id', None)
+        flask.session.pop('b_head', None)
+
+        return redirect('/user')
+    else:
+        http_warring = '' + \
+            '<hr class="main_hr">' + \
+            '<span>' + load_lang('http_warring') + '</span>' + \
+        ''
+
+        return easy_minify(flask.render_template(skin_check(),
+            imp = [load_lang('login'), wiki_set(), custom(), other2([0, 0])],
+            data =  '''
+                    <form method="post">
+                        <input placeholder="''' + load_lang('2fa_password') + '''" name="pw" type="password">
+                        <hr class=\"main_hr\">
+                        ''' + captcha_get() + '''
+                        <button type="submit">''' + load_lang('login') + '''</button>
+                        ''' + http_warring + '''
+                    </form>
+                    ''',
+            menu = [['user', load_lang('return')]]
+        ))

+ 1 - 1
route/login_check_key.py

@@ -3,6 +3,7 @@ from .tool.func import *
 def login_check_key_2(conn, tool):
     curs = conn.cursor()
 
+    # 난잡한 코드 정리 필요
     if flask.request.method == 'POST':
         if tool == 'check_pass_key':
             if 'c_id' in flask.session and flask.session['c_key'] == flask.request.form.get('key', None):
@@ -101,7 +102,6 @@ def login_check_key_2(conn, tool):
                         get_time()
                     ])
 
-                    flask.session['state'] = 1
                     flask.session['id'] = flask.session['c_id']
                     flask.session['head'] = ''
 

+ 0 - 1
route/login_register.py

@@ -116,7 +116,6 @@ def login_register_2(conn):
 
             curs.execute(db_change("insert into ua_d (name, ip, ua, today, sub) values (?, ?, ?, ?, '')"), [flask.request.form.get('id', None), ip, agent, get_time()])
 
-            flask.session['state'] = 1
             flask.session['id'] = flask.request.form.get('id', None)
             flask.session['head'] = ''
 

+ 1 - 1
route/tool/set_mark/tool.py

@@ -21,7 +21,7 @@ def db_change(data):
 
 def ip_check(d_type = 0):
     ip = ''
-    if d_type == 0 and (flask.session and ('state' and 'id') in flask.session):
+    if d_type == 0 and (flask.session and 'id' in flask.session):
         ip = flask.session['id']
     
     if ip == '':

+ 31 - 9
route/user_setting.py

@@ -11,15 +11,25 @@ def user_setting_2(conn, server_init):
 
     if ip_or_user(ip) == 0:
         if flask.request.method == 'POST':
-            auto_list = ['email', 'skin', 'lang']
+            auto_list = ['skin', 'lang', '2fa', '2fa_pw', '2fa_pw_encode']
+            pass_list = ['2fa', '2fa_pw_encode']
 
             for auto_data in auto_list:
-                if flask.request.form.get(auto_data, '') != '':
-                    curs.execute(db_change('select data from user_set where name = ? and id = ?'), [auto_data, ip])
-                    if curs.fetchall():
-                        curs.execute(db_change("update user_set set data = ? where name = ? and id = ?"), [flask.request.form.get(auto_data, ''), auto_data, ip])
-                    else:
-                        curs.execute(db_change("insert into user_set (name, id, data) values (?, ?, ?)"), [auto_data, ip, flask.request.form.get(auto_data, '')])
+                if auto_data in pass_list or flask.request.form.get(auto_data, '') != '':
+                    if auto_data != '2fa_pw_encode' or flask.request.form.get('2fa_pw', '') != '':
+                        if auto_data == '2fa_pw':
+                            get_data = pw_encode(flask.request.form.get(auto_data, ''))
+                        elif auto_data == '2fa_pw_encode':
+                            curs.execute(db_change("select encode from user where id = ?"), [ip])
+                            get_data = curs.fetchall()[0][0]
+                        else:
+                            get_data = flask.request.form.get(auto_data, '')
+                        
+                        curs.execute(db_change('select data from user_set where name = ? and id = ?'), [auto_data, ip])
+                        if curs.fetchall():
+                            curs.execute(db_change("update user_set set data = ? where name = ? and id = ?"), [get_data, auto_data, ip])
+                        else:
+                            curs.execute(db_change("insert into user_set (name, id, data) values (?, ?, ?)"), [auto_data, ip, get_data])
 
             conn.commit()
 
@@ -48,6 +58,14 @@ def user_setting_2(conn, server_init):
                 else:
                     div3 += '<option value="' + lang_data + '">' + see_data + '</option>'
 
+            curs.execute(db_change('select data from user_set where name = "2fa" and id = ?'), [ip])
+            fa_data = curs.fetchall()
+            fa_data = 'checked' if fa_data and fa_data[0][0] != '' else ''
+
+            curs.execute(db_change('select data from user_set where name = "2fa" and id = ?'), [ip])
+            fa_data_pw = curs.fetchall()
+            fa_data_pw = load_lang('2fa_password_change') if fa_data else load_lang('2fa_password')
+            
             http_warring = '' + \
                 '<hr class="main_hr">' + \
                 '<span>' + load_lang('http_warring') + '</span>' + \
@@ -57,12 +75,12 @@ def user_setting_2(conn, server_init):
                 imp = [load_lang('user_setting'), wiki_set(), custom(), other2([0, 0])],
                 data = '''
                     <form method="post">
-                        <span>''' + load_lang('id') + ''' : ''' + ip + '''</span>
+                        <span>''' + load_lang('id') + ''' : ''' + ip_pas(ip) + '''</span>
                         <hr class="main_hr">
                         <a href="/pw_change">(''' + load_lang('password_change') + ''')</a>
                         <hr class="main_hr">
                         <span>''' + load_lang('email') + ''' : ''' + email + '''</span> <a href="/email_change">(''' + load_lang('email_change') + ''')</a>
-                        <hr class="main_hr">
+                        <h2>''' + load_lang('main') + '''</h2>
                         <span>''' + load_lang('skin') + '''</span>
                         <hr class="main_hr">
                         <select name="skin">''' + div2 + '''</select>
@@ -70,6 +88,10 @@ def user_setting_2(conn, server_init):
                         <span>''' + load_lang('language') + '''</span>
                         <hr class="main_hr">
                         <select name="lang">''' + div3 + '''</select>
+                        <h2>''' + load_lang('2fa') + '''</h2>
+                        <input type="checkbox" name="2fa" value="on" ''' + fa_data + '''> ''' + load_lang('on') + '''
+                        <hr class="main_hr">
+                        <input type="password" name="2fa_pw" placeholder="''' + fa_data_pw + '''">
                         <hr class="main_hr">
                         <button type="submit">''' + load_lang('save') + '''</button>
                         ''' + http_warring + '''