Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
aa.gusti
/
opensipkd-base
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Settings
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit caf8c1c8
authored
Mar 17, 2026
by
aa.gustiana@gmail.com
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
perbaikan validasi login untuk mencegah percobaan login berlebihan
1 parent
febbaac4
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
8 deletions
opensipkd/base/views/user_login.py
opensipkd/base/views/user_login.py
View file @
caf8c1c
...
@@ -19,10 +19,13 @@ Perubahan Mendasar dari fungsi login adalah:
...
@@ -19,10 +19,13 @@ Perubahan Mendasar dari fungsi login adalah:
result object dari fungsi tersebut harus berupa class User()
result object dari fungsi tersebut harus berupa class User()
"""
"""
from
operator
import
ge
from
google.oauth2
import
id_token
from
google.auth.transport
import
requests
import
os
import
os
from
random
import
Random
from
random
import
Random
import
re
import
re
from
datetime
import
timedelta
,
datetime
from
datetime
import
date
,
timedelta
,
datetime
from
importlib
import
import_module
from
importlib
import
import_module
from
pyramid.request
import
Response
from
pyramid.request
import
Response
...
@@ -42,7 +45,7 @@ from . import one_hour, two_minutes
...
@@ -42,7 +45,7 @@ from . import one_hour, two_minutes
from
..models.users
import
User
,
ExternalIdentity
from
..models.users
import
User
,
ExternalIdentity
from
..models
import
Partner
from
..models
import
Partner
# , Partner
# , Partner
from
opensipkd.tools
import
create_now
,
set_user_log
,
get_settings
from
opensipkd.tools
import
create_now
,
set_user_log
,
get_settings
,
dmyhms
from
opensipkd.tools.buttons
import
btn_cancel
from
opensipkd.tools.buttons
import
btn_cancel
# from .. import get_urls
# from .. import get_urls
from
.base_views
import
CSRFSchema
,
BaseView
from
.base_views
import
CSRFSchema
,
BaseView
...
@@ -77,7 +80,18 @@ class Login(CSRFSchema):
...
@@ -77,7 +80,18 @@ class Login(CSRFSchema):
# http://deformdemo.repoze.org/interfield/
# http://deformdemo.repoze.org/interfield/
def
login_validator
(
form
,
value
):
def
login_validator
(
form
,
value
):
pass
exc
=
colander
.
Invalid
(
form
,
'Terlalu banyak percobaan'
)
request
=
form
.
request
if
request
.
session
.
get
(
"login_failed"
,
0
)
>
3
:
# message = "Login Gagal, terlalu banyak percobaan"
login_blocked
=
request
.
session
.
ses
[
"login_blocked"
]
if
login_blocked
and
login_blocked
>
datetime
.
now
():
exc
=
colander
.
Invalid
(
form
,
'Login Gagal, terlalu banyak percobaan, silahkan coba lagi setelah {}'
.
format
(
dmyhms
(
login_blocked
))
)
raise
exc
def
get_login_headers
(
request
,
user
):
def
get_login_headers
(
request
,
user
):
...
@@ -98,14 +112,25 @@ class LoginUser(object):
...
@@ -98,14 +112,25 @@ class LoginUser(object):
# self.identity=identity
# self.identity=identity
self
.
message
=
"Sukses Login"
self
.
message
=
"Sukses Login"
self
.
user
=
None
self
.
user
=
None
self
.
ses
=
request
.
session
self
.
ses
[
"login_failed"
]
=
self
.
ses
.
get
(
"login_failed"
,
0
)
self
.
ses
[
"login_blocked"
]
=
self
.
ses
.
get
(
"login_blocked"
)
def
login
(
self
,
values
,
user
=
None
):
def
login
(
self
,
values
,
user
=
None
):
settings
=
get_settings
()
self
.
user
=
user
and
user
or
User
.
get_by_identity
(
values
[
"username"
])
self
.
user
=
user
and
user
or
User
.
get_by_identity
(
values
[
"username"
])
if
not
self
.
user
or
not
UserService
.
check_password
(
if
not
self
.
user
or
not
UserService
.
check_password
(
self
.
user
,
values
[
"password"
]):
self
.
user
,
values
[
"password"
]):
self
.
message
=
"Login Gagal"
self
.
message
=
"Login Gagal"
set_user_log
(
self
.
message
,
self
.
request
,
log
,
values
[
"username"
])
set_user_log
(
self
.
message
,
self
.
request
,
log
,
values
[
"username"
])
self
.
ses
[
"login_failed"
]
+=
self
.
ses
.
get
(
"login_failed"
,
0
)
+
1
if
self
.
ses
[
"login_failed"
]
>
3
:
self
.
ses
[
"login_blocked"
]
=
datetime
.
now
()
+
\
timedelta
(
minutes
=
settings
.
get
(
"login_blocked_minutes"
,
1
))
return
return
self
.
ses
[
"login_failed"
]
=
0
self
.
ses
[
"login_blocked"
]
=
None
for
g
in
self
.
user
.
groups
:
for
g
in
self
.
user
.
groups
:
log
.
debug
(
f
"Group: {g.id} as {g.group_name}"
)
log
.
debug
(
f
"Group: {g.id} as {g.group_name}"
)
...
@@ -123,8 +148,6 @@ class Oauth2ParseExc(Exception):
...
@@ -123,8 +148,6 @@ class Oauth2ParseExc(Exception):
class
Oauth2UserExc
(
Exception
):
class
Oauth2UserExc
(
Exception
):
"""Error User Found"""
"""Error User Found"""
from
google.oauth2
import
id_token
from
google.auth.transport
import
requests
def
verify_android_token
(
token
,
web_client_id
):
def
verify_android_token
(
token
,
web_client_id
):
"""
"""
...
@@ -172,7 +195,8 @@ def verify_android_token(token, web_client_id):
...
@@ -172,7 +195,8 @@ def verify_android_token(token, web_client_id):
def
oauth2_login
(
request
,
params
=
None
):
def
oauth2_login
(
request
,
params
=
None
):
provider_name
=
params
and
params
[
"provider_name"
]
or
request
.
params
[
"provider_name"
]
provider_name
=
params
and
params
[
"provider_name"
]
or
request
.
params
[
"provider_name"
]
if
provider_name
==
"google"
:
if
provider_name
==
"google"
:
client_platform
=
params
and
params
.
get
(
"platform"
)
or
request
.
params
.
get
(
"platform"
)
or
"web"
client_platform
=
params
and
params
.
get
(
"platform"
)
or
request
.
params
.
get
(
"platform"
)
or
"web"
web_client_id
=
request
.
google_signin_client_id
web_client_id
=
request
.
google_signin_client_id
if
client_platform
==
"android"
:
if
client_platform
==
"android"
:
id_info
=
verify_android_token
(
id_info
=
verify_android_token
(
...
@@ -267,7 +291,7 @@ class ViewAuth(BaseView):
...
@@ -267,7 +291,7 @@ class ViewAuth(BaseView):
buttons
+=
(
Button
(
'register'
,
_
(
'Register'
)),)
buttons
+=
(
Button
(
'register'
,
_
(
'Register'
)),)
buttons
+=
(
Button
(
'reset'
,
_
(
'Reset'
)),
btn_cancel
,)
buttons
+=
(
Button
(
'reset'
,
_
(
'Reset'
)),
btn_cancel
,)
form
=
Form
(
schema
,
buttons
=
buttons
)
form
=
Form
(
schema
,
buttons
=
buttons
,
validator
=
login_validator
)
message
=
""
message
=
""
if
'cancel'
in
request
.
POST
:
if
'cancel'
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
home
)
return
HTTPFound
(
location
=
request
.
home
)
...
@@ -315,7 +339,7 @@ class ViewAuth(BaseView):
...
@@ -315,7 +339,7 @@ class ViewAuth(BaseView):
if
self
.
req
.
is_xhr
:
if
self
.
req
.
is_xhr
:
return
Response
(
json
=
{
"error"
:
{
"code"
:
-
1
,
return
Response
(
json
=
{
"error"
:
{
"code"
:
-
1
,
"msg"
:
login
.
message
},
"msg"
:
login
.
message
},
"data"
:[]})
"data"
:
[]})
next_url
=
f
"{request.route_url('base-login')}?next={next_url}"
next_url
=
f
"{request.route_url('base-login')}?next={next_url}"
return
HTTPFound
(
location
=
next_url
)
return
HTTPFound
(
location
=
next_url
)
...
@@ -420,6 +444,7 @@ class ViewAuth(BaseView):
...
@@ -420,6 +444,7 @@ class ViewAuth(BaseView):
return
dict
(
form
=
form
.
render
())
return
dict
(
form
=
form
.
render
())
def
xhr_response
(
user
,
headers
):
def
xhr_response
(
user
,
headers
):
partner
=
Partner
.
query_email
(
user
.
email
)
.
first
()
partner
=
Partner
.
query_email
(
user
.
email
)
.
first
()
mobile
=
partner
and
partner
.
mobile
or
""
mobile
=
partner
and
partner
.
mobile
or
""
...
@@ -439,6 +464,7 @@ def xhr_response(user, headers):
...
@@ -439,6 +464,7 @@ def xhr_response(user, headers):
}
}
return
Response
(
json
=
data
,
headerlist
=
headers
)
return
Response
(
json
=
data
,
headerlist
=
headers
)
def
redirect_login
(
request
,
user
):
def
redirect_login
(
request
,
user
):
set_user_log
(
"Login Sukses"
,
request
,
log
,
user
.
user_name
)
set_user_log
(
"Login Sukses"
,
request
,
log
,
user
.
user_name
)
for
g
in
user
.
groups
:
for
g
in
user
.
groups
:
...
@@ -638,6 +664,7 @@ class ViewPassword(BaseView):
...
@@ -638,6 +664,7 @@ class ViewPassword(BaseView):
sending_mail
(
self
.
req
,
user
,
subject
,
body
)
sending_mail
(
self
.
req
,
user
,
subject
,
body
)
return
dict
(
data
=
{
"message"
:
"Passcode sudah dikirim ke email Anda"
})
return
dict
(
data
=
{
"message"
:
"Passcode sudah dikirim ke email Anda"
})
class
ChangePasswordRequest
(
colander
.
Schema
):
class
ChangePasswordRequest
(
colander
.
Schema
):
new_password
=
colander
.
SchemaNode
(
new_password
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
CheckedPasswordWidget
())
colander
.
String
(),
widget
=
widget
.
CheckedPasswordWidget
())
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment