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 70b8d9a1
authored
Jan 14, 2026
by
aa.gustiana@gmail.com
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
android login
1 parent
033d3fe8
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
167 additions
and
7 deletions
opensipkd/base/models/partner.py
opensipkd/base/scripts/alembic/README
opensipkd/base/scripts/alembic/env.py
opensipkd/base/scripts/alembic/script.py.mako
opensipkd/base/views/templates/login.pt
opensipkd/base/views/user_login.py
opensipkd/base/models/partner.py
View file @
70b8d9a
...
@@ -23,10 +23,8 @@ class PartnerModel(NamaModel):
...
@@ -23,10 +23,8 @@ class PartnerModel(NamaModel):
fax
=
Column
(
String
(
16
))
fax
=
Column
(
String
(
16
))
mobile
=
Column
(
String
(
16
))
mobile
=
Column
(
String
(
16
))
website
=
Column
(
String
(
64
))
website
=
Column
(
String
(
64
))
# pic = Column(String(16))
is_vendor
=
Column
(
SmallInteger
,
nullable
=
False
,
)
# pic_mobile = Column(String(16))
is_customer
=
Column
(
SmallInteger
,
nullable
=
False
,
)
# pic_email = Column(String(16))
# pic_jabatan = Column(String(16))
@classmethod
@classmethod
def
query_email
(
cls
,
email
):
def
query_email
(
cls
,
email
):
...
@@ -43,8 +41,7 @@ class Partner(Base, PartnerModel):
...
@@ -43,8 +41,7 @@ class Partner(Base, PartnerModel):
kecamatan
=
Column
(
String
(
128
))
kecamatan
=
Column
(
String
(
128
))
kota
=
Column
(
String
(
128
))
kota
=
Column
(
String
(
128
))
provinsi
=
Column
(
String
(
128
))
provinsi
=
Column
(
String
(
128
))
is_vendor
=
Column
(
SmallInteger
,
nullable
=
False
,
)
is_customer
=
Column
(
SmallInteger
,
nullable
=
False
,
)
# bank = Column(String(16))
# bank = Column(String(16))
# bank_accnt = Column(String(16))
# bank_accnt = Column(String(16))
# user_id = Column(Integer, ForeignKey(User.id), nullable=True) # referensi ke login
# user_id = Column(Integer, ForeignKey(User.id), nullable=True) # referensi ke login
...
...
opensipkd/base/scripts/alembic/README
0 → 100644
View file @
70b8d9a
Generic single-database configuration.
\ No newline at end of file
\ No newline at end of file
opensipkd/base/scripts/alembic/env.py
0 → 100644
View file @
70b8d9a
from
logging.config
import
fileConfig
from
sqlalchemy
import
engine_from_config
from
sqlalchemy
import
pool
from
alembic
import
context
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config
=
context
.
config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
if
config
.
config_file_name
is
not
None
:
fileConfig
(
config
.
config_file_name
)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata
=
None
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
def
run_migrations_offline
()
->
None
:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url
=
config
.
get_main_option
(
"sqlalchemy.url"
)
context
.
configure
(
url
=
url
,
target_metadata
=
target_metadata
,
literal_binds
=
True
,
dialect_opts
=
{
"paramstyle"
:
"named"
},
)
with
context
.
begin_transaction
():
context
.
run_migrations
()
def
run_migrations_online
()
->
None
:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable
=
engine_from_config
(
config
.
get_section
(
config
.
config_ini_section
,
{}),
prefix
=
"sqlalchemy."
,
poolclass
=
pool
.
NullPool
,
)
with
connectable
.
connect
()
as
connection
:
context
.
configure
(
connection
=
connection
,
target_metadata
=
target_metadata
)
with
context
.
begin_transaction
():
context
.
run_migrations
()
if
context
.
is_offline_mode
():
run_migrations_offline
()
else
:
run_migrations_online
()
opensipkd/base/scripts/alembic/script.py.mako
0 → 100644
View file @
70b8d9a
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
${imports if imports else ""}
# revision identifiers, used by Alembic.
revision: str = ${repr(up_revision)}
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
def upgrade() -> None:
"""Upgrade schema."""
${upgrades if upgrades else "pass"}
def downgrade() -> None:
"""Downgrade schema."""
${downgrades if downgrades else "pass"}
opensipkd/base/views/templates/login.pt
View file @
70b8d9a
...
@@ -155,7 +155,7 @@
...
@@ -155,7 +155,7 @@
const
value
=
document
.
cookie
;
const
value
=
document
.
cookie
;
const
parts
=
value
.
split
(
`g_state=`
);
const
parts
=
value
.
split
(
`g_state=`
);
if
(
parts
.
length
===
2
)
{
if
(
parts
.
length
===
2
)
{
document
.
cookie
=
"max-age=0"
;
//
document.cookie = "max-age=0";
}
}
}
}
...
...
opensipkd/base/views/user_login.py
View file @
70b8d9a
...
@@ -23,6 +23,7 @@ import os
...
@@ -23,6 +23,7 @@ import os
import
re
import
re
from
datetime
import
timedelta
,
datetime
from
datetime
import
timedelta
,
datetime
from
importlib
import
import_module
from
importlib
import
import_module
from
pyramid.request
import
Response
from
pyramid.request
import
Response
import
colander
import
colander
from
deform
import
widget
,
Form
,
ValidationFailure
,
Button
from
deform
import
widget
,
Form
,
ValidationFailure
,
Button
...
@@ -121,10 +122,64 @@ class Oauth2ParseExc(Exception):
...
@@ -121,10 +122,64 @@ 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
):
"""
Verifies a Google ID token from an Android client on the backend.
Args:
token (str): The ID token string received from the Android app.
web_client_id (str): The Client ID for your *web application* in
Google Cloud Console.
Returns:
dict: The decoded user information (claims) if the token is valid.
Raises: ValueError if the token is invalid or unverified.
"""
try
:
# Create a request object for making HTTP requests to Google's servers
request
=
requests
.
Request
()
# Verify the token against Google's public keys
# The function automatically checks the token's signature, expiry,
# and if it was issued by accounts.google.com.
id_info
=
id_token
.
verify_oauth2_token
(
token
,
request
,
web_client_id
)
# Optional: Check if the token belongs to a specific Google Workspace domain (if required)
# if id_info.get('hd') != 'yourdomain.com':
# raise ValueError('Not a valid hosted domain.')
# Extract user information
user_id
=
id_info
[
'sub'
]
email
=
id_info
.
get
(
'email'
)
print
(
f
"Token verified for User ID: {user_id}, Email: {email}"
)
return
id_info
except
ValueError
as
e
:
# Invalid token (e.g., signature mismatch, expired, wrong audience)
print
(
f
"Invalid token: {e}"
)
raise
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"
web_client_id
=
request
.
google_signin_client_id
if
client_platform
==
"android"
:
id_info
=
verify_android_token
(
params
and
params
[
"id_token"
]
or
request
.
params
[
"id_token"
],
web_client_id
)
else
:
from
.base_google
import
googlesignin
from
.base_google
import
googlesignin
try
:
try
:
id_info
=
googlesignin
(
request
,
params
)
id_info
=
googlesignin
(
request
,
params
)
...
@@ -132,6 +187,7 @@ def oauth2_login(request, params=None):
...
@@ -132,6 +187,7 @@ def oauth2_login(request, params=None):
raise
Oauth2ParseExc
(
str
(
e
))
raise
Oauth2ParseExc
(
str
(
e
))
request
.
session
[
"id_info"
]
=
id_info
request
.
session
[
"id_info"
]
=
id_info
else
:
else
:
id_info
=
None
id_info
=
None
...
...
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