Compare commits
170 Commits
d8aeec0fde
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c63c3ddd92 | |||
| 3c57cb833e | |||
| c82b52fae6 | |||
| 6660e465f2 | |||
| 7c41346f51 | |||
| cc6115f30c | |||
| 86c892f154 | |||
| 37f37899df | |||
| c9cd3720e9 | |||
| d1e677056d | |||
| d6daa9bdba | |||
| 0c5a4194f0 | |||
| e25f788cbd | |||
| a7a9b207e2 | |||
| f7e3da51ae | |||
| 4212d3ed59 | |||
| bdae4eeb48 | |||
| dbd22fe285 | |||
| 894663ed38 | |||
| ec3edbd8d5 | |||
| 938f80b460 | |||
| 843ac3340c | |||
| 97e0effc61 | |||
| 8f9b9cf402 | |||
| 53d4d4536d | |||
| f2afeac3da | |||
| cf9c4d57c7 | |||
| ddf88501a1 | |||
| 681927911c | |||
| e862ff3717 | |||
| d3e72a2e4b | |||
| 8956ba03d5 | |||
| 048ffa00b6 | |||
| ba19cc0006 | |||
| f8557078cc | |||
| eace5933a1 | |||
| e38e8a91e5 | |||
| 2076fb1b81 | |||
| f734ef099b | |||
| c0e1e229cd | |||
| b5114b5224 | |||
| a3b4ac47b8 | |||
| 45e7169c3a | |||
| 3444c17026 | |||
| 98340db8df | |||
| e7b3f59dd0 | |||
| bc82cb123c | |||
| 2165a4400b | |||
| 6ca3905fed | |||
| d5708a964f | |||
| bb9b3a9735 | |||
| da68071e97 | |||
| 2e60fac840 | |||
| dab5a35870 | |||
| a35512e327 | |||
| 8a8bd50e28 | |||
| db90ce931f | |||
| 7639c749dc | |||
| 63461676f4 | |||
| eebd3fb746 | |||
| ba4b4eea94 | |||
| e583904693 | |||
| a2def0af79 | |||
| 6ccf76d1b2 | |||
| bc58249483 | |||
| 95a7972835 | |||
| e37aaff9cb | |||
| 77cffbbe9a | |||
| d623196c10 | |||
| 06e40853ad | |||
| d873965d37 | |||
| 275b9b12e3 | |||
| 81689f7512 | |||
| e3ad826826 | |||
| 9e98b581e4 | |||
| 41641b88e9 | |||
| a4d297a944 | |||
| 418713b0c7 | |||
| 087743453c | |||
| caed2b5925 | |||
| e18dc74dc2 | |||
| 9afa1d87e7 | |||
| 3cf9466cdb | |||
| 6c73e9990e | |||
| e8aa6189be | |||
| 47284a79c2 | |||
| 0121310941 | |||
| 76a4818a66 | |||
| 1ba32aa4c9 | |||
| edb3e07329 | |||
| f5304fae80 | |||
| d9be04541b | |||
| a7a20aebcf | |||
| 184675a9b7 | |||
| 197ee7127b | |||
| e3afb58634 | |||
| bafb67dabc | |||
| 08cb989975 | |||
| 455011fd99 | |||
| e8832f329a | |||
| a8df7d54bd | |||
| 39e1b925e5 | |||
| 42b4ade782 | |||
| c7f073c779 | |||
| 8126406e5f | |||
| fb5db25dce | |||
| f79e922fa0 | |||
| d796958d5e | |||
| 22ec115b35 | |||
| 5abb3fd2b7 | |||
| ed85918e7f | |||
| c5ec99d3e1 | |||
| 4af93b3d7e | |||
| afc3a10f51 | |||
| 3834ca2e37 | |||
| 0898213aa8 | |||
| cb08ecb53a | |||
| 70d775e0fc | |||
| 92c5bf5b46 | |||
| 6eed2be7f4 | |||
| 31782578f4 | |||
| 265ae0ac8b | |||
| cd126d2c59 | |||
| d3332f530f | |||
| 79e00de9f6 | |||
| 7e5da4948c | |||
| 21d4080baa | |||
| 2cd2a20065 | |||
| 74c0a215ed | |||
| e65fbafd36 | |||
| f0f5011e10 | |||
| 4ae86f0a57 | |||
| a55a435811 | |||
| 718c54f796 | |||
| 1b90e12fec | |||
| 9fd2316eeb | |||
| 3c9b959ad6 | |||
| 879d4b7092 | |||
| 562da693f1 | |||
| 7cd5211779 | |||
| 2399f8cd27 | |||
| b554a8783b | |||
| 37080b80f2 | |||
| 04c8f0094b | |||
| a034ea5ceb | |||
| c47353565b | |||
| 7d4d4049e8 | |||
| 6db196df28 | |||
| 8d9b975234 | |||
| efcc847405 | |||
| 4f6f9bf531 | |||
| 140da79f7f | |||
| 09328575ad | |||
| 4bb25a1eff | |||
| 91790330d2 | |||
| 40a5b4e878 | |||
| 50536caa00 | |||
| bf12ba76b6 | |||
| 84ab8949ec | |||
| f4582299aa | |||
| cbb95c6219 | |||
| ee20e5508e | |||
| 0ea219c721 | |||
| 19729c0809 | |||
| 6d63cce6d0 | |||
| 13021c47ce | |||
| 0a8f690714 | |||
| be7e5774ae | |||
| 7100199a17 | |||
| 8c75bbaf4a |
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,3 +1,10 @@
|
|||||||
.vscode/
|
.vscode/
|
||||||
*.log
|
*.log
|
||||||
*.exe
|
*.exe
|
||||||
|
console/
|
||||||
|
static/
|
||||||
|
config.json
|
||||||
|
*-firebase-*.json
|
||||||
|
maingate.zip
|
||||||
|
maingate.sh
|
||||||
|
maingate
|
||||||
|
|||||||
37
backup/firebase-jssdk/fb-ga.js
Normal file
37
backup/firebase-jssdk/fb-ga.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Import the functions you need from the SDKs you need
|
||||||
|
import { initializeApp } from './firebase-app.js';
|
||||||
|
import { getAnalytics, logEvent } from './firebase-analytics.js';
|
||||||
|
|
||||||
|
// TODO: Add SDKs for Firebase products that you want to use
|
||||||
|
// https://firebase.google.com/docs/web/setup#available-libraries
|
||||||
|
|
||||||
|
// Your web app's Firebase configuration
|
||||||
|
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
|
||||||
|
const firebaseConfig = {
|
||||||
|
apiKey: "{{.FBA_apiKey}}",
|
||||||
|
authDomain: "{{.FBA_authDomain}}",
|
||||||
|
databaseURL: "{{.FBA_databaseURL}}",
|
||||||
|
projectId: "{{.FBA_projectId}}",
|
||||||
|
storageBucket: "{{.FBA_storageBucket}}",
|
||||||
|
messagingSenderId: "{{.FBA_messagingSenderId}}",
|
||||||
|
appId: "{{.FBA_appId}}",
|
||||||
|
measurementId: "{{.FBA_measurementId}}"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize Firebase
|
||||||
|
const app = initializeApp(firebaseConfig);
|
||||||
|
const analytics = getAnalytics(app);
|
||||||
|
|
||||||
|
// LogEvent('DESKTOP_TEST8');
|
||||||
|
|
||||||
|
export function LogEvent(args){
|
||||||
|
|
||||||
|
if ( arguments.length == 1) {
|
||||||
|
logEvent(analytics, arguments[0]);
|
||||||
|
} else {
|
||||||
|
logEvent(analytics, arguments[0], arguments[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1
backup/firebase-jssdk/fb-ga.min.js
vendored
Normal file
1
backup/firebase-jssdk/fb-ga.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2376
backup/firebase-jssdk/fb-ga.rollup.js
Normal file
2376
backup/firebase-jssdk/fb-ga.rollup.js
Normal file
File diff suppressed because one or more lines are too long
3
backup/firebase-jssdk/firebase-analytics.js
Normal file
3
backup/firebase-jssdk/firebase-analytics.js
Normal file
File diff suppressed because one or more lines are too long
2522
backup/firebase-jssdk/firebase-app.js
Normal file
2522
backup/firebase-jssdk/firebase-app.js
Normal file
File diff suppressed because it is too large
Load Diff
537
backup/firebase-jssdk/js.js
Normal file
537
backup/firebase-jssdk/js.js
Normal file
File diff suppressed because one or more lines are too long
3
backup/firebase-jssdk/original/firebase-analytics.js
Normal file
3
backup/firebase-jssdk/original/firebase-analytics.js
Normal file
File diff suppressed because one or more lines are too long
2522
backup/firebase-jssdk/original/firebase-app.js
Normal file
2522
backup/firebase-jssdk/original/firebase-app.js
Normal file
File diff suppressed because it is too large
Load Diff
64
config.json
64
config.json
@ -1,64 +0,0 @@
|
|||||||
{
|
|
||||||
"region_storage" : {
|
|
||||||
"private" : {
|
|
||||||
"mongo" : "mongodb://192.168.8.94:27017/?replicaSet=repl01&retrywrites=false",
|
|
||||||
"redis" : {
|
|
||||||
"url" : "redis://192.168.8.94:6379",
|
|
||||||
"offset" : {
|
|
||||||
"cache" : 0,
|
|
||||||
"session" : 1,
|
|
||||||
"ranking" : 2,
|
|
||||||
"chat" : 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dev" : {
|
|
||||||
"mongo" : "mongodb://192.168.8.94:27017/?replicaSet=repl01&retrywrites=false",
|
|
||||||
"redis" : {
|
|
||||||
"url" : "redis://192.168.8.94:6379",
|
|
||||||
"offset" : {
|
|
||||||
"cache" : 0,
|
|
||||||
"session" : 1,
|
|
||||||
"ranking" : 2,
|
|
||||||
"chat" : 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"maingate_mongodb_url" : "mongodb://192.168.8.94:27017/?replicaSet=repl01&retrywrites=false",
|
|
||||||
"maingate_service_url" : "http://localhost/maingate",
|
|
||||||
"maingate_global_admins" : [
|
|
||||||
"rehjinh@action2quare.com"
|
|
||||||
],
|
|
||||||
"tavern_service_url" : "http://localhost/tavern",
|
|
||||||
"port" : 8080,
|
|
||||||
|
|
||||||
"postoffice_mongodb_url" : "mongodb://192.168.8.94:27017/?replicaSet=repl01&retrywrites=false",
|
|
||||||
"postoffice_service_url" : "http://localhost/maingate",
|
|
||||||
|
|
||||||
"autologin_ttl": 604800,
|
|
||||||
"redirect_base_url": "https://auth.action2quare.com",
|
|
||||||
"google_client_id" : "46698421246-fv2k7chr1j95ju1vm10ogq8prkjt8272.apps.googleusercontent.com",
|
|
||||||
"google_client_secret" : "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",
|
|
||||||
|
|
||||||
"twitter_oauth_key": "1045586021293862912-MSaciEnwsyNvgfjtmIjGTLA882X8DG",
|
|
||||||
"twitter_oauth_secret": "eclZpTlRQM3igThV7rVoVM5WnyJq9Eu9KfB2bWqvCIzUX",
|
|
||||||
"twitter_customer_key": "mZTsefCkkiwa3Qgj2WYbAGdS5",
|
|
||||||
"twitter_customer_secret": "300zHEJu17JuFupvigdi5s1B5nSiEAO1JqtcX9ZDMnUBJ8Bn6q",
|
|
||||||
|
|
||||||
"apple_client_id": "auth.service.action2quare.com",
|
|
||||||
"apple_privatekey": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgi3HkbNY93XdcNJVa\nAzR895cHxPXYeT0HnAOCzW5IOlOgCgYIKoZIzj0DAQehRANCAAS81nJzJcsZWtdr\n7sAeyqyHFoyCBdmsqI3fvLWYj/5M3MqgMI7pYyVbSmtXT9El/67Y4vz2e/9gllLy\ns0S/XoFo\n-----END PRIVATE KEY-----",
|
|
||||||
"apple_service_id": "auth.service.action2quare.com",
|
|
||||||
"apple_team_id": "YC94S4Z6CS",
|
|
||||||
"apple_key_id": "47UBTLARC8",
|
|
||||||
|
|
||||||
"microsoft_client_id": "ebc03204-a5b4-41bf-ac2b-5051615ccf33",
|
|
||||||
"microsoft_client_secret" : "fa78Q~9C4zEadeOf5ACSFsenP35jHVLKdW.jvcNr",
|
|
||||||
|
|
||||||
"gamepot_project_id": "dbfe1334-6dde-43e0-b8a9-cc0733d4c60e",
|
|
||||||
"gamepot_logincheckapi_url": "https://gamepot.apigw.ntruss.com/gpapps/v1/loginauth",
|
|
||||||
|
|
||||||
"firebase_admin_sdk_credentialfile": "kingdom-2b812-firebase-adminsdk-a6j68-d42ae01182.json"
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1 +1,43 @@
|
|||||||
{}
|
{
|
||||||
|
"maingate_mongodb_url": "mongodb://...",
|
||||||
|
"session_storage": "",
|
||||||
|
"session_ttl" : 3600,
|
||||||
|
|
||||||
|
"autologin_ttl": 604800,
|
||||||
|
"maximum_num_link_account": 10,
|
||||||
|
"redirect_base_url": "",
|
||||||
|
"google_client_id" : "",
|
||||||
|
"google_client_secret" : "",
|
||||||
|
|
||||||
|
"twitter_oauth_key": "",
|
||||||
|
"twitter_oauth_secret": "",
|
||||||
|
"twitter_customer_key": "",
|
||||||
|
"twitter_customer_secret": "",
|
||||||
|
|
||||||
|
"apple_client_id": "",
|
||||||
|
"apple_privatekey": "",
|
||||||
|
"apple_service_id": "",
|
||||||
|
"apple_team_id": "",
|
||||||
|
"apple_key_id": "",
|
||||||
|
|
||||||
|
"microsoft_client_id": "",
|
||||||
|
"microsoft_client_secret" : "",
|
||||||
|
|
||||||
|
"gamepot_project_id": "",
|
||||||
|
"gamepot_logincheckapi_url": "",
|
||||||
|
|
||||||
|
"firebase_admin_sdk_credentialfile": "",
|
||||||
|
|
||||||
|
"firebase_google_analytics_jssdk_apikey": "",
|
||||||
|
"firebase_google_analytics_jssdk_authdomain": "",
|
||||||
|
"firebase_google_analytics_jssdk_databaseurl": "",
|
||||||
|
"firebase_google_analytics_jssdk_projectid": "",
|
||||||
|
"firebase_google_analytics_jssdk_storagebucket": "",
|
||||||
|
"firebase_google_analytics_jssdk_messagingsenderid": "",
|
||||||
|
"firebase_google_analytics_jssdk_apiid": "",
|
||||||
|
"firebase_google_analytics_jssdk_measurementid": "",
|
||||||
|
|
||||||
|
"maingate_global_admins" : [
|
||||||
|
"mountain@action2quare.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"files": {
|
|
||||||
"main.css": "https://auth.action2quare.com/console/static/css/main.57f4cd54.css",
|
|
||||||
"main.js": "https://auth.action2quare.com/console/static/js/main.2ea4d7d1.js",
|
|
||||||
"static/js/811.8f231000.chunk.js": "https://auth.action2quare.com/console/static/js/811.8f231000.chunk.js",
|
|
||||||
"static/js/514.99ab97af.chunk.js": "https://auth.action2quare.com/console/static/js/514.99ab97af.chunk.js",
|
|
||||||
"static/css/617.e367b0e1.chunk.css": "https://auth.action2quare.com/console/static/css/617.e367b0e1.chunk.css",
|
|
||||||
"static/js/617.ef9b57b1.chunk.js": "https://auth.action2quare.com/console/static/js/617.ef9b57b1.chunk.js",
|
|
||||||
"static/js/348.a88c7705.chunk.js": "https://auth.action2quare.com/console/static/js/348.a88c7705.chunk.js",
|
|
||||||
"static/js/297.8ae1e5e0.chunk.js": "https://auth.action2quare.com/console/static/js/297.8ae1e5e0.chunk.js",
|
|
||||||
"static/js/340.ce8215ad.chunk.js": "https://auth.action2quare.com/console/static/js/340.ce8215ad.chunk.js",
|
|
||||||
"static/js/18.7ddf5096.chunk.js": "https://auth.action2quare.com/console/static/js/18.7ddf5096.chunk.js",
|
|
||||||
"static/js/664.556c2c72.chunk.js": "https://auth.action2quare.com/console/static/js/664.556c2c72.chunk.js",
|
|
||||||
"static/css/691.57000fb1.chunk.css": "https://auth.action2quare.com/console/static/css/691.57000fb1.chunk.css",
|
|
||||||
"static/js/691.b7fcc27d.chunk.js": "https://auth.action2quare.com/console/static/js/691.b7fcc27d.chunk.js",
|
|
||||||
"static/js/491.6101d763.chunk.js": "https://auth.action2quare.com/console/static/js/491.6101d763.chunk.js",
|
|
||||||
"static/js/998.7113153c.chunk.js": "https://auth.action2quare.com/console/static/js/998.7113153c.chunk.js",
|
|
||||||
"static/js/370.79fc8df3.chunk.js": "https://auth.action2quare.com/console/static/js/370.79fc8df3.chunk.js",
|
|
||||||
"static/js/176.44035bcc.chunk.js": "https://auth.action2quare.com/console/static/js/176.44035bcc.chunk.js",
|
|
||||||
"index.html": "https://auth.action2quare.com/console/index.html"
|
|
||||||
},
|
|
||||||
"entrypoints": [
|
|
||||||
"static/css/main.57f4cd54.css",
|
|
||||||
"static/js/main.2ea4d7d1.js"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@ -1 +0,0 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="https://auth.action2quare.com/console/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Maingate Console"/><link rel="apple-touch-icon" href="https://auth.action2quare.com/console/logo192.png"/><link rel="manifest" href="https://auth.action2quare.com/console/manifest.json"/><title>Maingate Console</title><script defer="defer" src="https://auth.action2quare.com/console/static/js/main.2ea4d7d1.js"></script><link href="https://auth.action2quare.com/console/static/css/main.57f4cd54.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"short_name": "Maingate Console",
|
|
||||||
"name": "Maingate Console",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "favicon.ico",
|
|
||||||
"sizes": "64x64 32x32 24x24 16x16",
|
|
||||||
"type": "image/x-icon"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo192.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "192x192"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo512.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "512x512"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start_url": ".",
|
|
||||||
"display": "standalone",
|
|
||||||
"theme_color": "#000000",
|
|
||||||
"background_color": "#ffffff"
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
# https://www.robotstxt.org/robotstxt.html
|
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
[data-simplebar]{align-content:flex-start;align-items:flex-start;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;position:relative}.simplebar-wrapper{height:inherit;max-height:inherit;max-width:inherit;overflow:hidden;width:inherit}.simplebar-mask{direction:inherit;height:auto!important;overflow:hidden;width:auto!important;z-index:0}.simplebar-mask,.simplebar-offset{bottom:0;left:0;margin:0;padding:0;position:absolute;right:0;top:0}.simplebar-offset{-webkit-overflow-scrolling:touch;box-sizing:inherit!important;direction:inherit!important;resize:none!important}.simplebar-content-wrapper{-ms-overflow-style:none;box-sizing:border-box!important;direction:inherit;display:block;height:100%;max-height:100%;max-width:100%;position:relative;scrollbar-width:none;width:auto}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{display:none;height:0;width:0}.simplebar-content:after,.simplebar-content:before{content:" ";display:table}.simplebar-placeholder{max-height:100%;max-width:100%;pointer-events:none;width:100%}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;flex-basis:0;flex-grow:inherit;flex-shrink:0;float:left;height:100%;margin:0;max-height:1px;max-width:1px;overflow:hidden;padding:0;pointer-events:none;position:relative;width:100%;z-index:-1}.simplebar-height-auto-observer{box-sizing:inherit;display:block;height:1000%;left:0;min-height:1px;min-width:1px;opacity:0;top:0;width:1000%;z-index:-1}.simplebar-height-auto-observer,.simplebar-track{overflow:hidden;pointer-events:none;position:absolute}.simplebar-track{bottom:0;right:0;z-index:1}[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;user-select:none;-webkit-user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{left:0;min-height:10px;position:absolute;right:0}.simplebar-scrollbar:before{background:#000;border-radius:7px;content:"";left:2px;opacity:0;position:absolute;right:2px;transition:opacity .2s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;transition:opacity 0s linear}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-track.simplebar-vertical .simplebar-scrollbar:before{bottom:2px;top:2px}.simplebar-track.simplebar-horizontal{height:11px;left:0}.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before{height:100%;left:2px;right:2px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{height:7px;left:0;min-height:0;min-width:10px;right:auto;top:2px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{left:0;right:auto}.hs-dummy-scrollbar-size{direction:rtl;height:500px;opacity:0;overflow-x:scroll;overflow-y:hidden;position:fixed;visibility:hidden;width:500px}.simplebar-hide-scrollbar{-ms-overflow-style:none;left:0;overflow-y:scroll;position:fixed;scrollbar-width:none;visibility:hidden}
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +0,0 @@
|
|||||||
/*! For license information please see 370.79fc8df3.chunk.js.LICENSE.txt */
|
|
||||||
"use strict";(self.webpackChunkmaingate_console=self.webpackChunkmaingate_console||[]).push([[370],{22370:function(e,t,r){r.d(t,{Z:function(){return m}});var n=r(47313),o=function(){return o=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},o.apply(this,arguments)};var s={exports:{}};var a,i,c,p;function l(){if(i)return a;i=1;return a="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"}s.exports=function(){if(p)return c;p=1;var e=l();function t(){}function r(){}return r.resetWarningCache=t,c=function(){function n(t,r,n,o,s,a){if(a!==e){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function o(){return n}n.isRequired=n;var s={array:n,bigint:n,bool:n,func:n,number:n,object:n,string:n,symbol:n,any:n,arrayOf:o,element:n,elementType:n,instanceOf:o,node:n,objectOf:o,oneOf:o,oneOfType:o,shape:o,exact:o,checkPropTypes:r,resetWarningCache:t};return s.PropTypes=s,s}}()();var u,f={exports:{}};u=f,function(){var e={}.hasOwnProperty;function t(){for(var r=[],n=0;n<arguments.length;n++){var o=arguments[n];if(o){var s=typeof o;if("string"===s||"number"===s)r.push(o);else if(Array.isArray(o)){if(o.length){var a=t.apply(null,o);a&&r.push(a)}}else if("object"===s)if(o.toString===Object.prototype.toString)for(var i in o)e.call(o,i)&&o[i]&&r.push(i);else r.push(o.toString())}}return r.join(" ")}u.exports?(t.default=t,u.exports=t):window.classNames=t}();var y=f.exports,m=(0,n.forwardRef)((function(e,t){var r,s=e.className,a=e.content,i=e.customClassName,c=e.height,p=e.icon,l=e.name,u=e.size,f=e.title,m=e.use,g=e.width,h=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"===typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]])}return r}(e,["className","content","customClassName","height","icon","name","size","title","use","width"]),x=(0,n.useState)(0),v=x[0],w=x[1],O=p||a||l;a&&process,l&&process,(0,n.useMemo)((function(){return w(v+1)}),[O,JSON.stringify(O)]);var b=(0,n.useMemo)((function(){return O&&"string"===typeof O&&O.includes("-")?O.replace(/([-_][a-z0-9])/gi,(function(e){return e.toUpperCase()})).replace(/-/gi,""):O}),[v]),d=f?"<title>".concat(f,"</title>"):"",T=(0,n.useMemo)((function(){return Array.isArray(O)?O:"string"===typeof O&&n.icons?n.icons[b]:void 0}),[v]),_=(0,n.useMemo)((function(){return Array.isArray(T)?T[1]||T[0]:T}),[v]),N=Array.isArray(T)&&T.length>1?T[0]:"64 64",S=h.viewBox||"0 0 ".concat(N),j=i?y(i):y("icon",((r={})["icon-".concat(u)]=u,r["icon-custom-size"]=c||g,r),s);return m?n.createElement("svg",o({xmlns:"http://www.w3.org/2000/svg",className:j},c&&{height:c},g&&{width:g},{role:"img"},h,{ref:t}),n.createElement("use",{href:m})):n.createElement("svg",o({xmlns:"http://www.w3.org/2000/svg",viewBox:S,className:j},c&&{height:c},g&&{width:g},{role:"img",dangerouslySetInnerHTML:{__html:d+_}},h,{ref:t}))}));m.propTypes={className:s.exports.string,content:s.exports.oneOfType([s.exports.array,s.exports.string]),customClassName:s.exports.string,height:s.exports.number,icon:s.exports.oneOfType([s.exports.array,s.exports.string]),name:s.exports.string,size:s.exports.oneOf(["custom","custom-size","sm","lg","xl","xxl","3xl","4xl","5xl","6xl","7xl","8xl","9xl"]),title:s.exports.any,use:s.exports.any,width:s.exports.number},m.displayName="CIcon"}}]);
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
/*!
|
|
||||||
Copyright (c) 2018 Jed Watson.
|
|
||||||
Licensed under the MIT License (MIT), see
|
|
||||||
http://jedwatson.github.io/classnames
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @license React v16.13.1
|
|
||||||
* react-is.development.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
"use strict";(self.webpackChunkmaingate_console=self.webpackChunkmaingate_console||[]).push([[514],{82514:function(e,s,l){l.r(s),l.d(s,{default:function(){return i}});l(47313);var c=l(27998),a=l(22370),n=["512 512","<path fill='var(--ci-primary-color, currentColor)' d='M479.6,399.716l-81.084-81.084-62.368-25.767A175.014,175.014,0,0,0,368,192c0-97.047-78.953-176-176-176S16,94.953,16,192,94.953,368,192,368a175.034,175.034,0,0,0,101.619-32.377l25.7,62.2L400.4,478.911a56,56,0,1,0,79.2-79.195ZM48,192c0-79.4,64.6-144,144-144s144,64.6,144,144S271.4,336,192,336,48,271.4,48,192ZM456.971,456.284a24.028,24.028,0,0,1-33.942,0l-76.572-76.572-23.894-57.835L380.4,345.771l76.573,76.572A24.028,24.028,0,0,1,456.971,456.284Z' class='ci-primary'/>"],r=l(46417);function i(){return(0,r.jsx)("div",{className:"bg-light min-vh-100 d-flex flex-row align-items-center",children:(0,r.jsx)(c.KB,{children:(0,r.jsx)(c.rb,{className:"justify-content-center",children:(0,r.jsxs)(c.b7,{md:6,children:[(0,r.jsxs)("div",{className:"clearfix",children:[(0,r.jsx)("h1",{className:"float-start display-3 me-4",children:"404"}),(0,r.jsx)("h4",{className:"pt-3",children:"not found."}),(0,r.jsx)("p",{className:"text-medium-emphasis float-start",children:"\ud574\ub2f9 \ud398\uc774\uc9c0\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uad00\ub9ac\uc790\uc5d0\uac8c \ubb38\uc758\ud558\uc138\uc694."})]}),(0,r.jsxs)(c.YR,{className:"input-prepend",children:[(0,r.jsx)(c.wV,{children:(0,r.jsx)(a.Z,{icon:n})}),(0,r.jsx)(c.jO,{type:"text",placeholder:"\ubb34\uc5c7\uc744 \ucc3e\uc73c\uc2dc\ub098\uc694?"}),(0,r.jsx)(c.u5,{color:"info",children:"\ucc3e\uae30"})]})]})})})})}}}]);
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,14 +0,0 @@
|
|||||||
/*!
|
|
||||||
Copyright (c) 2018 Jed Watson.
|
|
||||||
Licensed under the MIT License (MIT), see
|
|
||||||
http://jedwatson.github.io/classnames
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @license React v16.13.1
|
|
||||||
* react-is.development.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,130 +0,0 @@
|
|||||||
/*! *****************************************************************************
|
|
||||||
Copyright (c) Microsoft Corporation.
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
***************************************************************************** */
|
|
||||||
|
|
||||||
/*! @azure/msal-browser v2.31.0 2022-11-07 */
|
|
||||||
|
|
||||||
/*! @azure/msal-common v8.0.0 2022-11-07 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react-dom.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react-is.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react-jsx-runtime.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* react.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* scheduler.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* use-sync-external-store-shim.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license React
|
|
||||||
* use-sync-external-store-shim/with-selector.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @remix-run/router v1.0.3
|
|
||||||
*
|
|
||||||
* Copyright (c) Remix Software Inc.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE.md file in the root directory of this source tree.
|
|
||||||
*
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Router DOM v6.4.3
|
|
||||||
*
|
|
||||||
* Copyright (c) Remix Software Inc.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE.md file in the root directory of this source tree.
|
|
||||||
*
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Router v6.4.3
|
|
||||||
*
|
|
||||||
* Copyright (c) Remix Software Inc.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE.md file in the root directory of this source tree.
|
|
||||||
*
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @license React v16.13.1
|
|
||||||
* react-is.production.min.js
|
|
||||||
*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
553
core/api.go
553
core/api.go
@ -2,25 +2,21 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/md5"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
common "repositories.action2quare.com/ayo/gocommon"
|
"repositories.action2quare.com/ayo/gocommon"
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
@ -28,8 +24,7 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fileDocumentDesc struct {
|
type FileDocumentDesc struct {
|
||||||
Service string `bson:"service" json:"service"`
|
|
||||||
Key string `bson:"key" json:"key"`
|
Key string `bson:"key" json:"key"`
|
||||||
Src string `bson:"src" json:"src"`
|
Src string `bson:"src" json:"src"`
|
||||||
Link string `bson:"link" json:"link"`
|
Link string `bson:"link" json:"link"`
|
||||||
@ -39,7 +34,7 @@ type fileDocumentDesc struct {
|
|||||||
Contents []byte `bson:"contents,omitempty" json:"contents,omitempty"`
|
Contents []byte `bson:"contents,omitempty" json:"contents,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fd *fileDocumentDesc) save() error {
|
func (fd *FileDocumentDesc) Save() error {
|
||||||
// 새 파일 올라옴
|
// 새 파일 올라옴
|
||||||
if len(fd.Contents) == 0 {
|
if len(fd.Contents) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -68,168 +63,35 @@ func (fd *fileDocumentDesc) save() error {
|
|||||||
if fd.Extract {
|
if fd.Extract {
|
||||||
switch path.Ext(destFile) {
|
switch path.Ext(destFile) {
|
||||||
case ".zip":
|
case ".zip":
|
||||||
err = common.Unzip(destFile)
|
err = gocommon.Unzip(destFile)
|
||||||
case ".tar":
|
case ".tar":
|
||||||
err = common.Untar(destFile)
|
err = gocommon.Untar(destFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (caller apiCaller) isGlobalAdmin() bool {
|
|
||||||
if *noauth {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
email, ok := caller.userinfo["email"]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := caller.admins[email.(string)]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (caller apiCaller) writeAccessableServices(w http.ResponseWriter) {
|
|
||||||
services, editable := caller.getAccessableServices()
|
|
||||||
for _, r := range editable {
|
|
||||||
w.Header().Add("MG-X-SERVICE-EDITABLE", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Write([]byte("{"))
|
|
||||||
start := true
|
|
||||||
for _, v := range services {
|
|
||||||
if !start {
|
|
||||||
w.Write([]byte(","))
|
|
||||||
}
|
|
||||||
w.Write([]byte(fmt.Sprintf(`"%s":`, v.ServiceName)))
|
|
||||||
serptr := atomic.LoadPointer(&v.serviceSummarySerialized)
|
|
||||||
w.Write(*(*[]byte)(serptr))
|
|
||||||
start = false
|
|
||||||
}
|
|
||||||
w.Write([]byte("}"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (caller apiCaller) getAccessableServices() ([]*serviceDescription, []string) {
|
|
||||||
allservices := caller.mg.services.all()
|
|
||||||
|
|
||||||
admin := caller.isGlobalAdmin()
|
|
||||||
var email string
|
|
||||||
if !*noauth {
|
|
||||||
v, ok := caller.userinfo["email"]
|
|
||||||
if !ok {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
email = v.(string)
|
|
||||||
_, admin = caller.admins[email]
|
|
||||||
}
|
|
||||||
|
|
||||||
var output []*serviceDescription
|
|
||||||
var editable []string
|
|
||||||
for _, desc := range allservices {
|
|
||||||
if admin {
|
|
||||||
output = append(output, desc)
|
|
||||||
editable = append(editable, desc.ServiceName)
|
|
||||||
} else if desc.isValidAPIUser("*", email) {
|
|
||||||
output = append(output, desc)
|
|
||||||
if desc.isValidAPIUser("service", email) {
|
|
||||||
editable = append(editable, desc.ServiceName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(output, func(i, j int) bool {
|
|
||||||
return output[i].ServiceName < output[j].ServiceName
|
|
||||||
})
|
|
||||||
|
|
||||||
return output, editable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (caller apiCaller) isValidUser(service any, category string) (valid bool, admin bool) {
|
|
||||||
if *noauth {
|
|
||||||
return true, true
|
|
||||||
}
|
|
||||||
|
|
||||||
v, ok := caller.userinfo["email"]
|
|
||||||
if !ok {
|
|
||||||
logger.Println("isVaidUser failed. email is missing :", caller.userinfo)
|
|
||||||
return false, false
|
|
||||||
}
|
|
||||||
|
|
||||||
email := v.(string)
|
|
||||||
if _, ok := caller.admins[email]; ok {
|
|
||||||
return true, true
|
|
||||||
}
|
|
||||||
|
|
||||||
svcdesc := caller.mg.services.get(service)
|
|
||||||
if svcdesc == nil {
|
|
||||||
logger.Println("isVaidUser failed. service is missing :", service)
|
|
||||||
return false, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return svcdesc.isValidAPIUser(category, email), false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (caller apiCaller) filesAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) filesAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
hasAuth := caller.isGlobalAdmin()
|
allfiles, err := caller.mg.mongoClient.All(CollectionFile, options.Find().SetProjection(bson.M{
|
||||||
var email string
|
|
||||||
if !*noauth {
|
|
||||||
v, ok := caller.userinfo["email"]
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
email = v.(string)
|
|
||||||
_, hasAuth = caller.admins[email]
|
|
||||||
}
|
|
||||||
|
|
||||||
servicename := r.FormValue("service")
|
|
||||||
sh := caller.mg.services.get(servicename)
|
|
||||||
if sh == nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hasAuth {
|
|
||||||
if hasAuth = sh.isValidAPIUser("maintenance", email); !hasAuth {
|
|
||||||
hasAuth = sh.isValidAPIUser("service", email)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hasAuth {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var files []fileDocumentDesc
|
|
||||||
err := caller.mg.mongoClient.FindAllAs(CollectionFile, bson.M{
|
|
||||||
"service": servicename,
|
|
||||||
}, &files, options.Find().SetProjection(bson.M{
|
|
||||||
"contents": 0,
|
"contents": 0,
|
||||||
}))
|
}).SetReturnKey(false))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(files) > 0 {
|
if len(allfiles) > 0 {
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
return enc.Encode(files)
|
return enc.Encode(allfiles)
|
||||||
}
|
}
|
||||||
} else if r.Method == "DELETE" {
|
} else if r.Method == "DELETE" {
|
||||||
servicename := r.FormValue("service")
|
|
||||||
key := r.FormValue("key")
|
key := r.FormValue("key")
|
||||||
if len(servicename) == 0 || len(key) == 0 {
|
if len(key) == 0 {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := caller.mg.mongoClient.Delete(CollectionFile, bson.M{
|
_, err := caller.mg.mongoClient.Delete(CollectionFile, bson.M{
|
||||||
"service": servicename,
|
|
||||||
"key": key,
|
"key": key,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -245,11 +107,6 @@ var seq = uint32(0)
|
|||||||
|
|
||||||
func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
if r.Method == "PUT" {
|
if r.Method == "PUT" {
|
||||||
servicename := r.FormValue("service")
|
|
||||||
hasher := md5.New()
|
|
||||||
hasher.Write([]byte(servicename))
|
|
||||||
subfolder := hex.EncodeToString(hasher.Sum(nil))[:8]
|
|
||||||
|
|
||||||
infile, header, err := r.FormFile("file")
|
infile, header, err := r.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
@ -265,20 +122,19 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
var b [5]byte
|
var b [5]byte
|
||||||
binary.BigEndian.PutUint32(b[0:4], uint32(time.Now().Unix()))
|
binary.BigEndian.PutUint32(b[0:4], uint32(time.Now().Unix()))
|
||||||
b[4] = byte(atomic.AddUint32(&seq, 1) % 255)
|
b[4] = byte(atomic.AddUint32(&seq, 1) % 255)
|
||||||
rf := hex.EncodeToString(b[1:])
|
|
||||||
newidstr := subfolder + rf
|
|
||||||
newidbt, _ := hex.DecodeString(newidstr)
|
|
||||||
newidobj := primitive.NewObjectID()
|
|
||||||
copy(newidobj[:], newidbt[:8])
|
|
||||||
|
|
||||||
|
newidobj := primitive.NewObjectID()
|
||||||
|
copy(newidobj[:], b[1:])
|
||||||
|
|
||||||
|
rf := newidobj.Hex()
|
||||||
var link string
|
var link string
|
||||||
if extract {
|
if extract {
|
||||||
link = path.Join("static", subfolder, rf)
|
link = path.Join("static", rf)
|
||||||
} else {
|
} else {
|
||||||
link = path.Join("static", subfolder, rf, header.Filename)
|
link = path.Join("static", rf, header.Filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
newdoc := fileDocumentDesc{
|
newdoc := FileDocumentDesc{
|
||||||
Contents: contents,
|
Contents: contents,
|
||||||
Src: header.Filename,
|
Src: header.Filename,
|
||||||
Timestamp: time.Now().UTC().Unix(),
|
Timestamp: time.Now().UTC().Unix(),
|
||||||
@ -286,11 +142,9 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
Link: link,
|
Link: link,
|
||||||
Desc: desc,
|
Desc: desc,
|
||||||
Key: rf,
|
Key: rf,
|
||||||
Service: servicename,
|
|
||||||
}
|
}
|
||||||
_, _, err = caller.mg.mongoClient.UpsertOne(CollectionFile, bson.M{
|
_, _, err = caller.mg.mongoClient.UpsertOne(CollectionFile, bson.M{
|
||||||
"_id": newidobj,
|
"_id": newidobj,
|
||||||
"service": servicename,
|
|
||||||
"key": rf,
|
"key": rf,
|
||||||
}, newdoc)
|
}, newdoc)
|
||||||
|
|
||||||
@ -304,50 +158,83 @@ func (caller apiCaller) uploadAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) blockAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
mg := caller.mg
|
mg := caller.mg
|
||||||
queryvals := r.URL.Query()
|
logger.Println("blockAPI :", r.Method)
|
||||||
if r.Method == "GET" {
|
switch r.Method {
|
||||||
service := queryvals.Get("service")
|
case "GET":
|
||||||
|
target, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
|
||||||
if valid, _ := caller.isValidUser(service, "whitelist"); !valid {
|
if !ok {
|
||||||
logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
|
// 페이지네이션 해야할 듯
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
//json.NewEncoder(w).Encode(mg.bl.all())
|
||||||
return nil
|
} else if !target.IsZero() {
|
||||||
|
var blocked []blockinfo
|
||||||
|
if err := caller.mg.mongoClient.FindAllAs(CollectionBlock, bson.M{
|
||||||
|
"accid": target,
|
||||||
|
}, &blocked); err == nil {
|
||||||
|
json.NewEncoder(w).Encode(blocked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "PUT":
|
||||||
|
var targets struct {
|
||||||
|
Start primitive.DateTime
|
||||||
|
End primitive.DateTime
|
||||||
|
Accounts map[primitive.ObjectID]primitive.M // accid->meta
|
||||||
|
}
|
||||||
|
if err := gocommon.MakeDecoder(r).Decode(&targets); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(service) > 0 {
|
for accid, meta := range targets.Accounts {
|
||||||
|
bi := blockinfo{
|
||||||
|
Start: targets.Start,
|
||||||
|
End: targets.End,
|
||||||
|
Meta: meta,
|
||||||
|
}
|
||||||
|
|
||||||
all, err := mg.mongoClient.FindAll(CollectionWhitelist, bson.M{
|
_, err := mg.mongoClient.Collection(CollectionBlock).InsertOne(r.Context(), bi)
|
||||||
"service": service,
|
if err != nil {
|
||||||
})
|
logger.Println("account is not blocked. err :", err)
|
||||||
|
} else {
|
||||||
|
logger.Println("account is blocked :", meta)
|
||||||
|
mg.sessionProvider.RevokeAll(accid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "DELETE":
|
||||||
|
id := r.URL.Query().Get("id")
|
||||||
|
|
||||||
|
if len(id) == 0 {
|
||||||
|
return errors.New("id param is missing")
|
||||||
|
}
|
||||||
|
idobj, err := primitive.ObjectIDFromHex(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(all) > 0 {
|
mg.mongoClient.Delete(CollectionBlock, bson.M{"_id": idobj})
|
||||||
allraw, _ := json.Marshal(all)
|
|
||||||
w.Write(allraw)
|
|
||||||
}
|
}
|
||||||
} else {
|
return nil
|
||||||
logger.Println("service param is missing")
|
}
|
||||||
|
|
||||||
|
func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
mg := caller.mg
|
||||||
|
switch r.Method {
|
||||||
|
case "GET":
|
||||||
|
var all []whitelistmember
|
||||||
|
if err := mg.mongoClient.AllAs(CollectionWhitelist, &all); err == nil {
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
enc.Encode(all)
|
||||||
}
|
}
|
||||||
} else if r.Method == "PUT" {
|
case "PUT":
|
||||||
body, _ := io.ReadAll(r.Body)
|
body, _ := io.ReadAll(r.Body)
|
||||||
var member whitelistmember
|
var member whitelistmember
|
||||||
if err := json.Unmarshal(body, &member); err != nil {
|
if err := json.Unmarshal(body, &member); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if valid, _ := caller.isValidUser(member.Service, "whitelist"); !valid {
|
member.ExpiredAt = 0
|
||||||
logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
|
member.Id = primitive.NewObjectID()
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
member.Expired = 0
|
|
||||||
|
|
||||||
_, _, err := mg.mongoClient.Update(CollectionWhitelist, bson.M{
|
_, _, err := mg.mongoClient.Update(CollectionWhitelist, bson.M{
|
||||||
"_id": primitive.NewObjectID(),
|
"_id": member.Id,
|
||||||
}, bson.M{
|
}, bson.M{
|
||||||
"$set": &member,
|
"$set": &member,
|
||||||
}, options.Update().SetUpsert(true))
|
}, options.Update().SetUpsert(true))
|
||||||
@ -355,8 +242,9 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if r.Method == "DELETE" {
|
case "DELETE":
|
||||||
id := queryvals.Get("id")
|
id := r.URL.Query().Get("id")
|
||||||
|
|
||||||
if len(id) == 0 {
|
if len(id) == 0 {
|
||||||
return errors.New("id param is missing")
|
return errors.New("id param is missing")
|
||||||
}
|
}
|
||||||
@ -381,25 +269,21 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
|
|||||||
|
|
||||||
func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
mg := caller.mg
|
mg := caller.mg
|
||||||
queryvals := r.URL.Query()
|
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
name := queryvals.Get("name")
|
logger.Println("serviceAPI :", r.URL.Path)
|
||||||
if len(name) > 0 {
|
if mg.service().Id.IsZero() {
|
||||||
if valid, _ := caller.isValidUser(name, "*"); !valid {
|
logger.Println(" id is zero")
|
||||||
logger.Println("serviceAPI failed. not vaild user :", r.Method, caller.userinfo)
|
newService := serviceDescription{
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
Id: primitive.NewObjectID(),
|
||||||
return nil
|
}
|
||||||
|
if err := newService.prepare(caller.mg); err != nil {
|
||||||
|
logger.Println(" prepare failed :", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&newService))
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid, admin := caller.isValidUser(name, "service"); valid || admin {
|
w.Write(mg.service().serviceSerialized)
|
||||||
w.Header().Add("MG-X-SERVICE-EDITABLE", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
serptr := atomic.LoadPointer(&mg.services.get(name).serviceSerialized)
|
|
||||||
w.Write(*(*[]byte)(serptr))
|
|
||||||
} else {
|
|
||||||
caller.writeAccessableServices(w)
|
|
||||||
}
|
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
body, _ := io.ReadAll(r.Body)
|
body, _ := io.ReadAll(r.Body)
|
||||||
var service serviceDescription
|
var service serviceDescription
|
||||||
@ -407,25 +291,13 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if service.Id.IsZero() {
|
if len(service.ServerApiTokens) == 0 {
|
||||||
if caller.isGlobalAdmin() {
|
service.ServerApiTokens = []primitive.ObjectID{
|
||||||
service.Id = primitive.NewObjectID()
|
primitive.NewObjectIDFromTimestamp(time.Now().Add(-time.Hour * 24 * 30 * 465)),
|
||||||
} else {
|
|
||||||
logger.Println("serviceAPI failed. not vaild user :", r.Method, caller.userinfo)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
} else if valid, _ := caller.isValidUser(service.Id, "service"); !valid {
|
|
||||||
logger.Println("serviceAPI failed. not vaild user :", r.Method, caller.userinfo)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := bson.M{"_id": service.Id}
|
filter := bson.M{"_id": service.Id}
|
||||||
if len(service.ServiceCode) == 0 {
|
|
||||||
service.ServiceCode = hex.EncodeToString(service.Id[6:])
|
|
||||||
}
|
|
||||||
|
|
||||||
success, _, err := mg.mongoClient.Update(CollectionService, filter, bson.M{
|
success, _, err := mg.mongoClient.Update(CollectionService, filter, bson.M{
|
||||||
"$set": &service,
|
"$set": &service,
|
||||||
}, options.Update().SetUpsert(true))
|
}, options.Update().SetUpsert(true))
|
||||||
@ -445,32 +317,9 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
|
|
||||||
func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
mg := caller.mg
|
mg := caller.mg
|
||||||
queryvals := r.URL.Query()
|
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
name := queryvals.Get("name")
|
w.Write(mg.service().divisionsSerialized)
|
||||||
if len(name) > 0 {
|
|
||||||
if valid, _ := caller.isValidUser(name, "*"); !valid {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid, admin := caller.isValidUser(name, "maintenance"); valid || admin {
|
|
||||||
w.Header().Add("MG-X-SERVICE-EDITABLE", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
serptr := atomic.LoadPointer(&mg.services.get(name).divisionsSerialized)
|
|
||||||
w.Write(*(*[]byte)(serptr))
|
|
||||||
} else {
|
|
||||||
caller.writeAccessableServices(w)
|
|
||||||
}
|
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
servicename := queryvals.Get("name")
|
|
||||||
if valid, _ := caller.isValidUser(servicename, "service"); !valid {
|
|
||||||
logger.Println("maintenanceAPI failed. not vaild user :", r.Method, caller.userinfo)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var divs map[string]*Division
|
var divs map[string]*Division
|
||||||
dec := json.NewDecoder(r.Body)
|
dec := json.NewDecoder(r.Body)
|
||||||
if err := dec.Decode(&divs); err != nil {
|
if err := dec.Decode(&divs); err != nil {
|
||||||
@ -479,7 +328,7 @@ func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, _, err := mg.mongoClient.Update(CollectionService, bson.M{
|
_, _, err := mg.mongoClient.Update(CollectionService, bson.M{
|
||||||
"service": servicename,
|
"_id": mg.service().Id,
|
||||||
}, bson.M{
|
}, bson.M{
|
||||||
"$set": bson.M{"divisions": divs},
|
"$set": bson.M{"divisions": divs},
|
||||||
}, options.Update().SetUpsert(false))
|
}, options.Update().SetUpsert(false))
|
||||||
@ -493,120 +342,106 @@ func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (caller apiCaller) accountAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) couponAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
mg := caller.mg
|
switch r.Method {
|
||||||
queryvals := r.URL.Query()
|
case "PUT":
|
||||||
if r.Method == "GET" {
|
// 쿠폰 생성
|
||||||
service := queryvals.Get("service")
|
logger.Println("begin generateCoupons")
|
||||||
if len(service) == 0 {
|
generateCoupons(caller.mg.mongoClient, w, r)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if valid, _ := caller.isValidUser(service, "account"); !valid {
|
case "POST":
|
||||||
logger.Println("accountAPI failed. not vaild user :", r.Method, caller.userinfo)
|
// TODO : 쿠폰 사용
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
// 쿠폰 사용 표시 해주고 내용을 응답
|
||||||
return nil
|
logger.Println("begin useCoupon")
|
||||||
}
|
useCoupon(caller.mg.mongoClient, w, r)
|
||||||
|
|
||||||
var accdoc primitive.M
|
case "GET":
|
||||||
if v := queryvals.Get("accid"); len(v) == 0 {
|
// 쿠폰 조회
|
||||||
email := queryvals.Get("email")
|
if r.Form.Has("code") {
|
||||||
platform := queryvals.Get("platform")
|
// 쿠폰 코드 조회
|
||||||
if len(email) == 0 || len(platform) == 0 {
|
logger.Println("begin queryCoupon")
|
||||||
return nil
|
queryCoupon(caller.mg.mongoClient, w, r)
|
||||||
}
|
} else if r.Form.Has("name") {
|
||||||
|
// 쿠폰 코드 다운
|
||||||
found, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
|
logger.Println("begin downloadCoupons")
|
||||||
"email": email,
|
downloadCoupons(caller.mg.mongoClient, w, r)
|
||||||
"platform": platform,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if found == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if idobj, ok := found["_id"]; ok {
|
|
||||||
svcdoc, err := mg.mongoClient.FindOne(common.CollectionName(service), bson.M{
|
|
||||||
"_id": idobj,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if svcdoc != nil {
|
|
||||||
found["accid"] = svcdoc["accid"]
|
|
||||||
}
|
|
||||||
|
|
||||||
accdoc = found
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
accid, err := primitive.ObjectIDFromHex(v)
|
// 쿠폰 이름 목록
|
||||||
if err != nil {
|
logger.Println("begin listAllCouponNames")
|
||||||
return err
|
listAllCouponNames(caller.mg.mongoClient, w, r)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
svcdoc, err := mg.mongoClient.FindOne(common.CollectionName(service), bson.M{
|
type accountlinkinfo struct {
|
||||||
|
Uid string `json:"uid"`
|
||||||
|
Platform string `json:"platform"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (caller apiCaller) userinfoAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
mg := caller.mg
|
||||||
|
if r.Method == "GET" {
|
||||||
|
// 계정 조회
|
||||||
|
accid, _ := gocommon.ReadObjectIDFormValue(r.Form, "accid")
|
||||||
|
if len(accid) > 0 {
|
||||||
|
all, err := mg.mongoClient.FindAll(CollectionAccount, bson.M{
|
||||||
"accid": accid,
|
"accid": accid,
|
||||||
})
|
}, options.Find().SetProjection(bson.M{"_id": 1, "accid": 1}))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
found, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
|
var linkinfos []accountlinkinfo
|
||||||
"_id": svcdoc["_id"],
|
for _, doc := range all {
|
||||||
})
|
id := doc["_id"].(primitive.ObjectID)
|
||||||
|
|
||||||
|
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
|
||||||
|
"_id": id,
|
||||||
|
}, options.FindOne().SetProjection(bson.M{"_id": 1, "platform": 1, "uid": 1}))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logger.Error("link failed. FindOneAndUpdate link err:", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if found != nil {
|
var info accountlinkinfo
|
||||||
found["accid"] = accid
|
info.Platform = link["platform"].(string)
|
||||||
}
|
info.Uid = link["uid"].(string)
|
||||||
accdoc = found
|
linkinfos = append(linkinfos, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
if accdoc != nil {
|
enc := json.NewEncoder(w)
|
||||||
accdoc["code"] = service
|
enc.Encode(linkinfos)
|
||||||
delete(accdoc, "uid")
|
|
||||||
delete(accdoc, "_id")
|
|
||||||
|
|
||||||
var bi blockinfo
|
|
||||||
if err := mg.mongoClient.FindOneAs(CollectionBlock, bson.M{
|
|
||||||
"code": service,
|
|
||||||
"accid": accdoc["accid"],
|
|
||||||
}, &bi); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bi.Start.Time().IsZero() && bi.End.Time().After(time.Now().UTC()) {
|
|
||||||
accdoc["blocked"] = bi
|
|
||||||
}
|
|
||||||
return json.NewEncoder(w).Encode(accdoc)
|
|
||||||
}
|
}
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
var account struct {
|
r.ParseMultipartForm(32 << 20)
|
||||||
Code string
|
var body struct {
|
||||||
Accid string
|
Platform string
|
||||||
Blocked blockinfo
|
Uid []string
|
||||||
}
|
}
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||||
body, _ := io.ReadAll(r.Body)
|
|
||||||
if err := json.Unmarshal(body, &account); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
accid, _ := primitive.ObjectIDFromHex(account.Accid)
|
if len(body.Platform) > 0 && len(body.Uid) > 0 {
|
||||||
if !account.Blocked.Start.Time().IsZero() && account.Blocked.Start.Time().After(time.Now().UTC()) {
|
output := make(map[string]any)
|
||||||
if _, _, err := mg.mongoClient.Update(CollectionBlock, bson.M{
|
for _, uid := range body.Uid {
|
||||||
"code": account.Code,
|
link, err := mg.mongoClient.FindOne(CollectionLink, bson.M{
|
||||||
"accid": accid,
|
"platform": body.Platform,
|
||||||
}, bson.M{
|
"uid": uid,
|
||||||
"$set": account.Blocked,
|
}, options.FindOne().SetProjection(bson.M{"_id": 1}))
|
||||||
}, options.Update().SetUpsert(true)); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
output[uid] = link["_id"]
|
||||||
|
}
|
||||||
|
json.NewEncoder(w).Encode(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,24 +449,27 @@ var errApiTokenMissing = errors.New("mg-x-api-token is missing")
|
|||||||
|
|
||||||
func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
mg := caller.mg
|
mg := caller.mg
|
||||||
|
|
||||||
|
if !*devflag {
|
||||||
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
||||||
if len(apitoken) == 0 {
|
if len(apitoken) == 0 {
|
||||||
return errApiTokenMissing
|
return errApiTokenMissing
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := mg.apiTokenToService.get(apitoken); !exists {
|
apitokenObj, _ := primitive.ObjectIDFromHex(apitoken)
|
||||||
|
if !mg.service().isValidToken(apitokenObj) {
|
||||||
return fmt.Errorf("mg-x-api-token is not valid : %s", apitoken)
|
return fmt.Errorf("mg-x-api-token is not valid : %s", apitoken)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var noauth = flag.Bool("noauth", false, "")
|
|
||||||
|
|
||||||
type apiCaller struct {
|
type apiCaller struct {
|
||||||
userinfo map[string]any
|
userinfo map[string]any
|
||||||
admins map[string]bool
|
globalAdmins map[string]bool
|
||||||
mg *Maingate
|
mg *Maingate
|
||||||
|
apiToken primitive.ObjectID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -647,9 +485,11 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
|||||||
r.Body.Close()
|
r.Body.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
r.ParseMultipartForm(32 << 20)
|
||||||
|
|
||||||
var userinfo map[string]any
|
var userinfo map[string]any
|
||||||
|
|
||||||
if !*noauth {
|
if !*devflag {
|
||||||
authheader := r.Header.Get("Authorization")
|
authheader := r.Header.Get("Authorization")
|
||||||
if len(authheader) == 0 {
|
if len(authheader) == 0 {
|
||||||
logger.Println("Authorization header is not valid :", authheader)
|
logger.Println("Authorization header is not valid :", authheader)
|
||||||
@ -683,20 +523,35 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
|||||||
ptr := atomic.LoadPointer(&mg.admins)
|
ptr := atomic.LoadPointer(&mg.admins)
|
||||||
adminsptr := (*globalAdmins)(ptr)
|
adminsptr := (*globalAdmins)(ptr)
|
||||||
|
|
||||||
if adminsptr.modtime != common.ConfigModTime() {
|
if adminsptr.modtime != gocommon.ConfigModTime() {
|
||||||
var config globalAdmins
|
var config globalAdmins
|
||||||
if err := common.LoadConfig(&config); err == nil {
|
if err := gocommon.LoadConfig(&config); err == nil {
|
||||||
config.parse()
|
config.parse()
|
||||||
adminsptr = &config
|
adminsptr = &config
|
||||||
atomic.StorePointer(&mg.admins, unsafe.Pointer(adminsptr))
|
atomic.StorePointer(&mg.admins, unsafe.Pointer(adminsptr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var apiTokenObj primitive.ObjectID
|
||||||
|
if !*devflag {
|
||||||
|
apiToken := r.Header.Get("MG-X-API-TOKEN")
|
||||||
|
if len(apiToken) > 0 {
|
||||||
|
obj, err := primitive.ObjectIDFromHex(apiToken)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiTokenObj = obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.Println("api call :", r.URL.Path, r.Method, r.URL.Query(), userinfo)
|
logger.Println("api call :", r.URL.Path, r.Method, r.URL.Query(), userinfo)
|
||||||
caller := apiCaller{
|
caller := apiCaller{
|
||||||
userinfo: userinfo,
|
userinfo: userinfo,
|
||||||
admins: adminsptr.emails,
|
globalAdmins: adminsptr.emails,
|
||||||
mg: mg,
|
mg: mg,
|
||||||
|
apiToken: apiTokenObj,
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -706,14 +561,18 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = caller.whitelistAPI(w, r)
|
err = caller.whitelistAPI(w, r)
|
||||||
} else if strings.HasSuffix(r.URL.Path, "/config") {
|
} else if strings.HasSuffix(r.URL.Path, "/config") {
|
||||||
err = caller.configAPI(w, r)
|
err = caller.configAPI(w, r)
|
||||||
} else if strings.HasSuffix(r.URL.Path, "/account") {
|
|
||||||
err = caller.accountAPI(w, r)
|
|
||||||
} else if strings.HasSuffix(r.URL.Path, "/upload") {
|
} else if strings.HasSuffix(r.URL.Path, "/upload") {
|
||||||
err = caller.uploadAPI(w, r)
|
err = caller.uploadAPI(w, r)
|
||||||
} else if strings.HasSuffix(r.URL.Path, "/maintenance") {
|
} else if strings.HasSuffix(r.URL.Path, "/maintenance") {
|
||||||
err = caller.maintenanceAPI(w, r)
|
err = caller.maintenanceAPI(w, r)
|
||||||
} else if strings.HasSuffix(r.URL.Path, "/files") {
|
} else if strings.HasSuffix(r.URL.Path, "/files") {
|
||||||
err = caller.filesAPI(w, r)
|
err = caller.filesAPI(w, r)
|
||||||
|
} else if strings.HasSuffix(r.URL.Path, "/block") {
|
||||||
|
err = caller.blockAPI(w, r)
|
||||||
|
} else if strings.HasSuffix(r.URL.Path, "/coupon") {
|
||||||
|
err = caller.couponAPI(w, r)
|
||||||
|
} else if strings.HasSuffix(r.URL.Path, "/userinfo") {
|
||||||
|
err = caller.userinfoAPI(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
377
core/api_coupon.go
Normal file
377
core/api_coupon.go
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
"repositories.action2quare.com/ayo/gocommon"
|
||||||
|
coupon "repositories.action2quare.com/ayo/gocommon/coupon"
|
||||||
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CollectionCoupon = gocommon.CollectionName("coupon")
|
||||||
|
CollectionCouponUse = gocommon.CollectionName("coupon_use")
|
||||||
|
)
|
||||||
|
|
||||||
|
type couponDoc struct {
|
||||||
|
Name string `json:"name" bson:"name"`
|
||||||
|
Effect string `json:"effect" bson:"effect"`
|
||||||
|
Desc string `json:"desc" bson:"desc"`
|
||||||
|
Total int64 `json:"total" bson:"total"`
|
||||||
|
Remains []string `json:"remains,omitempty" bson:"remains,omitempty"`
|
||||||
|
Used []string `json:"used,omitempty" bson:"used,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCouponKey(roundnum uint32, uid []byte) string {
|
||||||
|
left := binary.BigEndian.Uint16(uid[0:2])
|
||||||
|
right := binary.BigEndian.Uint16(uid[2:4])
|
||||||
|
multi := uint32(left) * uint32(right)
|
||||||
|
xor := roundnum ^ multi
|
||||||
|
|
||||||
|
final := make([]byte, 8)
|
||||||
|
binary.LittleEndian.PutUint32(final, xor)
|
||||||
|
copy(final[4:], uid)
|
||||||
|
return fmt.Sprintf("%s-%s-%s-%s", hex.EncodeToString(final[0:2]), hex.EncodeToString(final[2:4]), hex.EncodeToString(final[4:6]), hex.EncodeToString(final[6:8]))
|
||||||
|
}
|
||||||
|
|
||||||
|
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
|
func makeCouponCodes(name string, count int) (string, map[string]string) {
|
||||||
|
checkunique := make(map[string]bool)
|
||||||
|
keys := make(map[string]string)
|
||||||
|
uid := make([]byte, 4)
|
||||||
|
|
||||||
|
roundHash, roundnum := coupon.MakeCouponRoundHash(name)
|
||||||
|
|
||||||
|
for len(keys) < count {
|
||||||
|
r.Read(uid)
|
||||||
|
|
||||||
|
code := makeCouponKey(roundnum, uid)
|
||||||
|
|
||||||
|
if _, ok := checkunique[code]; !ok {
|
||||||
|
checkunique[code] = true
|
||||||
|
keys[hex.EncodeToString(uid)] = code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return roundHash, keys
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||||
|
name, _ := gocommon.ReadStringFormValue(r.Form, "name")
|
||||||
|
effect, _ := gocommon.ReadStringFormValue(r.Form, "effect")
|
||||||
|
count, _ := gocommon.ReadIntegerFormValue(r.Form, "count")
|
||||||
|
desc, _ := gocommon.ReadStringFormValue(r.Form, "desc")
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
logger.Println("[generateCoupons] count == 0")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
roundHash, _ := coupon.MakeCouponRoundHash(name)
|
||||||
|
roundObj, _ := primitive.ObjectIDFromHex(roundHash + roundHash + roundHash)
|
||||||
|
|
||||||
|
if count < 0 {
|
||||||
|
// 무한 쿠폰이므로 그냥 문서 생성해 주고 끝
|
||||||
|
if _, _, err := mongoClient.Update(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, bson.M{
|
||||||
|
"$set": &couponDoc{
|
||||||
|
Name: name,
|
||||||
|
Effect: effect,
|
||||||
|
Desc: desc,
|
||||||
|
Total: -1,
|
||||||
|
},
|
||||||
|
}, options.Update().SetUpsert(true)); err != nil {
|
||||||
|
logger.Println("[generateCoupons] Update failed :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// effect가 비어있으면 기존의 roundName에 갯수를 추가해 준다
|
||||||
|
// effect가 비어있지 않으면 roundName이 겹쳐서는 안된다.
|
||||||
|
coupondoc, err := mongoClient.FindOne(CollectionCoupon, bson.M{"_id": roundObj})
|
||||||
|
if err != nil {
|
||||||
|
logger.Println("[generateCoupons] FindOne failed :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lastKeys := make(map[string]bool)
|
||||||
|
if coupondoc != nil {
|
||||||
|
if r, ok := coupondoc["remains"]; ok {
|
||||||
|
remains := r.(primitive.A)
|
||||||
|
for _, uid := range remains {
|
||||||
|
lastKeys[uid.(string)] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issuedKeys := make(map[string]string)
|
||||||
|
for len(issuedKeys) < int(count) {
|
||||||
|
_, vs := makeCouponCodes(name, int(count)-len(issuedKeys))
|
||||||
|
for k, v := range vs {
|
||||||
|
if _, ok := lastKeys[k]; !ok {
|
||||||
|
// 기존 키와 중복되지 않는 것만
|
||||||
|
issuedKeys[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var coupons []string
|
||||||
|
var uids []string
|
||||||
|
for uid, code := range issuedKeys {
|
||||||
|
uids = append(uids, uid)
|
||||||
|
coupons = append(coupons, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
if coupondoc != nil {
|
||||||
|
_, _, err = mongoClient.Update(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, bson.M{
|
||||||
|
"$push": bson.M{"remains": bson.M{"$each": uids}},
|
||||||
|
"$inc": bson.M{"total": count},
|
||||||
|
}, options.Update().SetUpsert(true))
|
||||||
|
} else {
|
||||||
|
_, _, err = mongoClient.Update(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, bson.M{
|
||||||
|
"$push": bson.M{"remains": bson.M{"$each": uids}},
|
||||||
|
"$set": couponDoc{
|
||||||
|
Name: name,
|
||||||
|
Effect: effect,
|
||||||
|
Desc: desc,
|
||||||
|
Total: count,
|
||||||
|
},
|
||||||
|
}, options.Update().SetUpsert(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Println("[generateCoupons] Update failed :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
enc.Encode(coupons)
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadCoupons(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||||
|
name, _ := gocommon.ReadStringFormValue(r.Form, "name")
|
||||||
|
if len(name) == 0 {
|
||||||
|
logger.Println("[downloadCoupons] name is empty")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
round, _ := coupon.MakeCouponRoundHash(name)
|
||||||
|
|
||||||
|
roundObj, err := primitive.ObjectIDFromHex(round + round + round)
|
||||||
|
if err != nil {
|
||||||
|
// 유효하지 않은 형식의 code
|
||||||
|
logger.Println("[downloadCoupons] ObjectIDFromHex failed :", err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var coupon couponDoc
|
||||||
|
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "remains": 1})); err != nil {
|
||||||
|
logger.Println("[downloadCoupons] FindOne failed :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
roundnum := binary.BigEndian.Uint32(roundObj[:])
|
||||||
|
var coupons []string
|
||||||
|
for _, uid := range coupon.Remains {
|
||||||
|
decUid, err := hex.DecodeString(uid)
|
||||||
|
if err != nil {
|
||||||
|
logger.Println("downloadCoupons Fail", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
coupons = append(coupons, makeCouponKey(roundnum, decUid))
|
||||||
|
}
|
||||||
|
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
enc.Encode(coupons)
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||||
|
code, _ := gocommon.ReadStringFormValue(r.Form, "code")
|
||||||
|
if len(code) == 0 {
|
||||||
|
logger.Println("[queryCoupon] code is empty")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
round, _ := coupon.DisolveCouponCode(code)
|
||||||
|
if len(round) == 0 {
|
||||||
|
// 유효하지 않은 형식의 code
|
||||||
|
// 쿠폰 이름일 수 있으므로 round hash를 계산한다.
|
||||||
|
round, _ = coupon.MakeCouponRoundHash(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
roundObj, err := primitive.ObjectIDFromHex(round + round + round)
|
||||||
|
if err != nil {
|
||||||
|
// 유효하지 않은 형식의 code
|
||||||
|
logger.Println("[queryCoupon] ObjectIDFromHex failed :", err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var coupon couponDoc
|
||||||
|
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, &coupon, options.FindOne().SetProjection(bson.M{"effect": 1, "name": 1, "reason": 1, "total": 1, "desc": 1}).SetReturnKey(false)); err != nil {
|
||||||
|
logger.Println("[queryCoupon] FindOneAs failed :", err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
enc.Encode(coupon)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listAllCouponNames(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||||
|
all, err := mongoClient.FindAll(CollectionCoupon, bson.M{}, options.Find().SetProjection(bson.M{"name": 1}))
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var names []string
|
||||||
|
for _, doc := range all {
|
||||||
|
names = append(names, doc["name"].(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
enc := json.NewEncoder(w)
|
||||||
|
enc.Encode(names)
|
||||||
|
}
|
||||||
|
|
||||||
|
func useCoupon(mongoClient gocommon.MongoClient, w http.ResponseWriter, r *http.Request) {
|
||||||
|
acc, ok := gocommon.ReadObjectIDFormValue(r.Form, "accid")
|
||||||
|
if !ok || acc.IsZero() {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
code, _ := gocommon.ReadStringFormValue(r.Form, "code")
|
||||||
|
code = strings.TrimSpace(code)
|
||||||
|
if len(code) == 0 {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
round, key := coupon.DisolveCouponCode(code)
|
||||||
|
if len(round) == 0 {
|
||||||
|
// couponId가 쿠폰 이름일 수도 있다. 무한 쿠폰
|
||||||
|
round, _ = coupon.MakeCouponRoundHash(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 쿠폰 사용 유무 검사
|
||||||
|
alreadyused, err := mongoClient.Exists(CollectionCouponUse, bson.M{
|
||||||
|
"_id": acc,
|
||||||
|
"rounds": round,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Println(err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if alreadyused {
|
||||||
|
// 이미 이 라운드의 쿠폰을 사용한 적이 있다.
|
||||||
|
w.WriteHeader(http.StatusConflict)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var coupon couponDoc
|
||||||
|
roundObj, _ := primitive.ObjectIDFromHex(round + round + round)
|
||||||
|
if len(key) == 0 {
|
||||||
|
// 무한 쿠폰일 수 있으므로 존재하는지 확인
|
||||||
|
if err := mongoClient.FindOneAs(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, &coupon, options.FindOne().SetProjection(bson.M{"_id": 0, "effect": 1, "name": 1, "reason": 1, "total": 1})); err != nil {
|
||||||
|
logger.Println(err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if coupon.Total > 0 {
|
||||||
|
// 무한 쿠폰 아니네?
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 2. 쿠폰을 하나 꺼냄
|
||||||
|
matched, _, err := mongoClient.Update(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
"remains": key,
|
||||||
|
}, bson.M{
|
||||||
|
"$pull": bson.M{"remains": key},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Println(err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
// 쿠폰이 없다.
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. round의 효과 읽기
|
||||||
|
if err := mongoClient.FindOneAndUpdateAs(CollectionCoupon, bson.M{
|
||||||
|
"_id": roundObj,
|
||||||
|
}, bson.M{
|
||||||
|
"$push": bson.M{"used": key},
|
||||||
|
}, &coupon, options.FindOneAndUpdate().SetProjection(bson.M{"effect": 1})); err != nil {
|
||||||
|
logger.Println(err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(coupon.Effect) == 0 {
|
||||||
|
// 쿠폰이 없네?
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 쿠폰은 사용한 것으로 표시
|
||||||
|
// 이제 이 아래에서 실패하면 이 쿠폰은 못쓴다.
|
||||||
|
updated, _, err := mongoClient.Update(CollectionCouponUse, bson.M{
|
||||||
|
"_id": acc,
|
||||||
|
}, bson.M{
|
||||||
|
"$push": bson.M{"rounds": round},
|
||||||
|
"$set": bson.M{round + ".id": code},
|
||||||
|
"$currentDate": bson.M{round + ".ts": true},
|
||||||
|
}, options.Update().SetUpsert(true))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Println(err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !updated {
|
||||||
|
logger.Println(err)
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte(coupon.Effect))
|
||||||
|
}
|
||||||
9
core/api_test.go
Normal file
9
core/api_test.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMakeLocalUniqueId(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
694
core/maingate.go
694
core/maingate.go
@ -7,21 +7,21 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
common "repositories.action2quare.com/ayo/gocommon"
|
"repositories.action2quare.com/ayo/gocommon"
|
||||||
|
"repositories.action2quare.com/ayo/gocommon/flagx"
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
"repositories.action2quare.com/ayo/gocommon/session"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
@ -34,26 +34,31 @@ import (
|
|||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var devflag = flagx.Bool("dev", false, "")
|
||||||
|
var noauth = flagx.Bool("noauth", false, "")
|
||||||
|
var authtype = flagx.String("auth", "on", "on|off|both")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
CollectionLink = common.CollectionName("link")
|
CollectionLink = gocommon.CollectionName("link")
|
||||||
CollectionAuth = common.CollectionName("auth")
|
CollectionWhitelist = gocommon.CollectionName("whitelist")
|
||||||
CollectionWhitelist = common.CollectionName("whitelist")
|
CollectionService = gocommon.CollectionName("service")
|
||||||
CollectionService = common.CollectionName("service")
|
CollectionAccount = gocommon.CollectionName("account")
|
||||||
CollectionFile = common.CollectionName("file")
|
CollectionFile = gocommon.CollectionName("file")
|
||||||
CollectionBlock = common.CollectionName("block")
|
CollectionBlock = gocommon.CollectionName("block")
|
||||||
CollectionPlatformLoginToken = common.CollectionName("platform_login_token") //-- 각 플랫폼에 로그인 및 권한 받아오는 과정에 사용하는 Key
|
CollectionPlatformLoginToken = gocommon.CollectionName("platform_login_token") //-- 각 플랫폼에 로그인 및 권한 받아오는 과정에 사용하는 Key
|
||||||
CollectionUserToken = common.CollectionName("usertoken")
|
CollectionUserToken = gocommon.CollectionName("usertoken")
|
||||||
CollectionGamepotUserInfo = common.CollectionName("gamepot_userinfo") //-- 클라로부터 수집된 gamepot 정보 - server to server로 유효성이 검증되진 않았지만 수집은 한다.
|
CollectionGamepotUserInfo = gocommon.CollectionName("gamepot_userinfo") //-- 클라로부터 수집된 gamepot 정보 - server to server로 유효성이 검증되진 않았지만 수집은 한다.
|
||||||
CollectionFirebaseUserInfo = common.CollectionName("firebase_userinfo") //-- Firebase UserInfo
|
CollectionFirebaseUserInfo = gocommon.CollectionName("firebase_userinfo") //-- Firebase UserInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
AuthPlatformSteamSDK = "steam"
|
||||||
AuthPlatformFirebaseAuth = "firebase"
|
AuthPlatformFirebaseAuth = "firebase"
|
||||||
AuthPlatformGamepot = "gamepot"
|
|
||||||
AuthPlatformGoogle = "google"
|
AuthPlatformGoogle = "google"
|
||||||
AuthPlatformMicrosoft = "microsoft"
|
AuthPlatformMicrosoft = "microsoft"
|
||||||
AuthPlatformApple = "apple"
|
AuthPlatformApple = "apple"
|
||||||
AuthPlatformTwitter = "twitter"
|
AuthPlatformTwitter = "twitter"
|
||||||
|
AuthPlatformHybeim = "hybeim"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -62,105 +67,20 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SessionTTL() time.Duration {
|
func SessionTTL() time.Duration {
|
||||||
if *common.Devflag {
|
if *devflag {
|
||||||
return sessionTTLDev
|
return sessionTTLDev
|
||||||
}
|
}
|
||||||
|
|
||||||
return sessionTTL
|
return sessionTTL
|
||||||
}
|
}
|
||||||
|
|
||||||
type mongoAuthCell struct {
|
|
||||||
src *common.Authinfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
if *common.Devflag {
|
|
||||||
hostname, _ := os.Hostname()
|
|
||||||
CollectionLink = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionLink)))
|
|
||||||
CollectionAuth = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionAuth)))
|
|
||||||
CollectionWhitelist = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionWhitelist)))
|
|
||||||
CollectionService = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionService)))
|
|
||||||
CollectionBlock = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionBlock)))
|
|
||||||
CollectionPlatformLoginToken = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionPlatformLoginToken)))
|
|
||||||
CollectionUserToken = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionUserToken)))
|
|
||||||
CollectionGamepotUserInfo = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionGamepotUserInfo)))
|
|
||||||
CollectionFirebaseUserInfo = common.CollectionName(fmt.Sprintf("%s-%s", hostname, string(CollectionFirebaseUserInfo)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ac *mongoAuthCell) ToAuthinfo() *common.Authinfo {
|
|
||||||
if ac.src == nil {
|
|
||||||
logger.Error("mongoAuthCell ToAuthinfo failed. ac.src is nil")
|
|
||||||
}
|
|
||||||
return ac.src
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ac *mongoAuthCell) ToBytes() []byte {
|
|
||||||
bt, _ := json.Marshal(ac.src)
|
|
||||||
return bt
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeAuthCollection(mongoClient common.MongoClient, sessionTTL time.Duration) *common.AuthCollection {
|
|
||||||
authcoll := common.MakeAuthCollection(sessionTTL)
|
|
||||||
authcoll.SessionRemoved = func(sk string) {
|
|
||||||
skid, _ := primitive.ObjectIDFromHex(sk)
|
|
||||||
mongoClient.Delete(CollectionAuth, bson.M{
|
|
||||||
"sk": skid,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
authcoll.QuerySession = func(sk string, token string) common.AuthinfoCell {
|
|
||||||
skid, _ := primitive.ObjectIDFromHex(sk)
|
|
||||||
var outcell mongoAuthCell
|
|
||||||
err := mongoClient.FindOneAs(CollectionAuth, bson.M{
|
|
||||||
"sk": skid,
|
|
||||||
}, &outcell.src, options.FindOne().SetHint("skonly"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("QuerySession failed :", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if outcell.src == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &outcell
|
|
||||||
}
|
|
||||||
|
|
||||||
return authcoll
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiTokenMap struct {
|
|
||||||
sync.Mutex
|
|
||||||
tokenToService map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tm *apiTokenMap) add(token string, serviceCode string) {
|
|
||||||
tm.Lock()
|
|
||||||
defer tm.Unlock()
|
|
||||||
|
|
||||||
tm.tokenToService[token] = serviceCode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tm *apiTokenMap) remove(token string) {
|
|
||||||
tm.Lock()
|
|
||||||
defer tm.Unlock()
|
|
||||||
|
|
||||||
delete(tm.tokenToService, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tm *apiTokenMap) get(token string) (code string, exists bool) {
|
|
||||||
tm.Lock()
|
|
||||||
defer tm.Unlock()
|
|
||||||
|
|
||||||
code, exists = tm.tokenToService[token]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type maingateConfig struct {
|
type maingateConfig struct {
|
||||||
|
session.SessionConfig `json:",inline"`
|
||||||
|
MustUseChecksum bool `json:"maingate_must_checksum"`
|
||||||
Mongo string `json:"maingate_mongodb_url"`
|
Mongo string `json:"maingate_mongodb_url"`
|
||||||
SessionTTL int64 `json:"maingate_session_ttl"`
|
|
||||||
Autologin_ttl int64 `json:"autologin_ttl"`
|
Autologin_ttl int64 `json:"autologin_ttl"`
|
||||||
|
AccDelTTL int64 `json:"acc_del_ttl"`
|
||||||
|
MaximumNumLinkAccount int64 `json:"maximum_num_link_account"`
|
||||||
RedirectBaseUrl string `json:"redirect_base_url"`
|
RedirectBaseUrl string `json:"redirect_base_url"`
|
||||||
GoogleClientId string `json:"google_client_id"`
|
GoogleClientId string `json:"google_client_id"`
|
||||||
GoogleClientSecret string `json:"google_client_secret"`
|
GoogleClientSecret string `json:"google_client_secret"`
|
||||||
@ -178,6 +98,26 @@ type maingateConfig struct {
|
|||||||
GamepotProjectId string `json:"gamepot_project_id"`
|
GamepotProjectId string `json:"gamepot_project_id"`
|
||||||
GamepotLoginCheckAPIURL string `json:"gamepot_logincheckapi_url"`
|
GamepotLoginCheckAPIURL string `json:"gamepot_logincheckapi_url"`
|
||||||
FirebaseAdminSDKCredentialFile string `json:"firebase_admin_sdk_credentialfile"`
|
FirebaseAdminSDKCredentialFile string `json:"firebase_admin_sdk_credentialfile"`
|
||||||
|
SteamAppId string `json:"steam_app_id"`
|
||||||
|
SteamPublisherAuthKey string `json:"steam_publisher_authkey"`
|
||||||
|
GlobalMaingateToken string `json:"maingate_api_token"`
|
||||||
|
HybeImProjectIdstring string `json:"hybeim_projectid"`
|
||||||
|
HybeImServiceIdstring string `json:"hybeim_serviceid"`
|
||||||
|
HybeImAccessKey string `json:"hybeim_acesskey"`
|
||||||
|
HybeImEndPoint string `json:"hybeim_Endpoint"`
|
||||||
|
|
||||||
|
Firebase_Google_Analytics_JS_SDK_Config
|
||||||
|
}
|
||||||
|
|
||||||
|
type Firebase_Google_Analytics_JS_SDK_Config struct {
|
||||||
|
FGA_apiKey string `json:"firebase_google_analytics_jssdk_apikey"`
|
||||||
|
FGA_authDomain string `json:"firebase_google_analytics_jssdk_authdomain"`
|
||||||
|
FGA_databaseURL string `json:"firebase_google_analytics_jssdk_databaseurl"`
|
||||||
|
FGA_projectId string `json:"firebase_google_analytics_jssdk_projectid"`
|
||||||
|
FGA_storageBucket string `json:"firebase_google_analytics_jssdk_storagebucket"`
|
||||||
|
FGA_messagingSenderId string `json:"firebase_google_analytics_jssdk_messagingsenderid"`
|
||||||
|
FGA_appId string `json:"firebase_google_analytics_jssdk_apiid"`
|
||||||
|
FGA_measurementId string `json:"ffirebase_google_analytics_jssdk_measurementid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type globalAdmins struct {
|
type globalAdmins struct {
|
||||||
@ -192,127 +132,54 @@ func (ga *globalAdmins) parse() {
|
|||||||
parsed[admin] = true
|
parsed[admin] = true
|
||||||
}
|
}
|
||||||
ga.emails = parsed
|
ga.emails = parsed
|
||||||
ga.modtime = common.ConfigModTime()
|
ga.modtime = gocommon.ConfigModTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
type servicelist struct {
|
type firebaseClient struct {
|
||||||
services unsafe.Pointer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sl *servicelist) init(total []*serviceDescription) error {
|
|
||||||
next := make(map[string]*serviceDescription)
|
|
||||||
for _, service := range total {
|
|
||||||
next[service.ServiceName] = service
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic.StorePointer(&sl.services, unsafe.Pointer(&next))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sl *servicelist) add(s *serviceDescription) {
|
|
||||||
ptr := atomic.LoadPointer(&sl.services)
|
|
||||||
src := (*map[string]*serviceDescription)(ptr)
|
|
||||||
|
|
||||||
next := map[string]*serviceDescription{}
|
|
||||||
for k, v := range *src {
|
|
||||||
next[k] = v
|
|
||||||
}
|
|
||||||
next[s.ServiceName] = s
|
|
||||||
atomic.StorePointer(&sl.services, unsafe.Pointer(&next))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sl *servicelist) get(sn any) *serviceDescription {
|
|
||||||
ptr := atomic.LoadPointer(&sl.services)
|
|
||||||
src := *(*map[string]*serviceDescription)(ptr)
|
|
||||||
|
|
||||||
switch sn := sn.(type) {
|
|
||||||
case string:
|
|
||||||
return src[sn]
|
|
||||||
|
|
||||||
case primitive.ObjectID:
|
|
||||||
for _, desc := range src {
|
|
||||||
if desc.Id == sn {
|
|
||||||
return desc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sl *servicelist) all() map[string]*serviceDescription {
|
|
||||||
ptr := atomic.LoadPointer(&sl.services)
|
|
||||||
src := (*map[string]*serviceDescription)(ptr)
|
|
||||||
|
|
||||||
next := map[string]*serviceDescription{}
|
|
||||||
for k, v := range *src {
|
|
||||||
next[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
return next
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sl *servicelist) remove(uid primitive.ObjectID) (out *serviceDescription) {
|
|
||||||
ptr := atomic.LoadPointer(&sl.services)
|
|
||||||
src := (*map[string]*serviceDescription)(ptr)
|
|
||||||
|
|
||||||
next := map[string]*serviceDescription{}
|
|
||||||
var targetkey string
|
|
||||||
out = nil
|
|
||||||
for k, v := range *src {
|
|
||||||
next[k] = v
|
|
||||||
if v.Id == uid {
|
|
||||||
targetkey = k
|
|
||||||
out = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete(next, targetkey)
|
|
||||||
atomic.StorePointer(&sl.services, unsafe.Pointer(&next))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maingate :
|
|
||||||
type Maingate struct {
|
|
||||||
maingateConfig
|
|
||||||
|
|
||||||
mongoClient common.MongoClient
|
|
||||||
|
|
||||||
auths *common.AuthCollection
|
|
||||||
services servicelist
|
|
||||||
admins unsafe.Pointer
|
|
||||||
apiTokenToService apiTokenMap
|
|
||||||
tokenEndpoints map[string]string
|
|
||||||
authorizationEndpoints map[string]string
|
|
||||||
userinfoEndpoint map[string]string
|
|
||||||
jwksUri map[string]string
|
|
||||||
webTemplate map[string]*template.Template
|
|
||||||
firebaseAppClient *auth.Client
|
firebaseAppClient *auth.Client
|
||||||
firebaseAppContext context.Context
|
firebaseAppContext context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maingate :
|
||||||
|
type Maingate struct {
|
||||||
|
mongoClient gocommon.MongoClient
|
||||||
|
|
||||||
|
sessionProvider session.Provider
|
||||||
|
//services servicelist
|
||||||
|
serviceptr unsafe.Pointer
|
||||||
|
admins unsafe.Pointer
|
||||||
|
|
||||||
|
tokenEndpoints map[string]string
|
||||||
|
authorizationEndpoints map[string]string
|
||||||
|
userinfoEndpoint map[string]string
|
||||||
|
jwksUri map[string]string
|
||||||
|
|
||||||
|
firebase *firebaseClient
|
||||||
|
}
|
||||||
|
|
||||||
|
var config maingateConfig
|
||||||
|
|
||||||
// New :
|
// New :
|
||||||
func New(ctx context.Context) (*Maingate, error) {
|
func New(ctx context.Context) (*Maingate, error) {
|
||||||
var config maingateConfig
|
if err := gocommon.LoadConfig(&config); err != nil {
|
||||||
if err := common.LoadConfig(&config); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var admins globalAdmins
|
var admins globalAdmins
|
||||||
if err := common.LoadConfig(&admins); err == nil {
|
if err := gocommon.LoadConfig(&admins); err == nil {
|
||||||
admins.parse()
|
admins.parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(config.SessionStorage) == 0 {
|
||||||
|
return nil, errors.New("maingate_session_storage is missing")
|
||||||
|
}
|
||||||
|
|
||||||
if config.SessionTTL == 0 {
|
if config.SessionTTL == 0 {
|
||||||
config.SessionTTL = 3600
|
config.SessionTTL = 3600
|
||||||
}
|
}
|
||||||
|
|
||||||
mg := Maingate{
|
mg := Maingate{
|
||||||
maingateConfig: config,
|
|
||||||
services: servicelist{},
|
|
||||||
admins: unsafe.Pointer(&admins),
|
admins: unsafe.Pointer(&admins),
|
||||||
apiTokenToService: apiTokenMap{
|
|
||||||
tokenToService: make(map[string]string),
|
|
||||||
},
|
|
||||||
tokenEndpoints: make(map[string]string),
|
tokenEndpoints: make(map[string]string),
|
||||||
authorizationEndpoints: make(map[string]string),
|
authorizationEndpoints: make(map[string]string),
|
||||||
userinfoEndpoint: make(map[string]string),
|
userinfoEndpoint: make(map[string]string),
|
||||||
@ -321,26 +188,43 @@ func New(ctx context.Context) (*Maingate, error) {
|
|||||||
|
|
||||||
err := mg.prepare(ctx)
|
err := mg.prepare(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("mg.prepare() failed :", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
opt := option.WithCredentialsFile(mg.FirebaseAdminSDKCredentialFile)
|
if len(*authtype) == 0 {
|
||||||
|
*authtype = "on"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !*noauth && (*authtype == "on" || *authtype == "both") {
|
||||||
|
if len(config.FirebaseAdminSDKCredentialFile) > 0 {
|
||||||
|
opt := option.WithCredentialsFile(config.FirebaseAdminSDKCredentialFile)
|
||||||
firebaseApp, err := firebase.NewApp(context.Background(), nil, opt)
|
firebaseApp, err := firebase.NewApp(context.Background(), nil, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("firebase admin error initializing app failed :", err)
|
logger.Error("firebase admin error initializing app failed :", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mg.firebaseAppContext = ctx
|
firebaseAppClient, err := firebaseApp.Auth(ctx)
|
||||||
mg.firebaseAppClient, err = firebaseApp.Auth(mg.firebaseAppContext)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Println("FirebaseAppClient error getting Auth client:", err)
|
logger.Println("FirebaseAppClient error getting Auth client:", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mg.firebase = &firebaseClient{
|
||||||
|
firebaseAppContext: ctx,
|
||||||
|
firebaseAppClient: firebaseAppClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &mg, nil
|
return &mg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mg *Maingate) service() *serviceDescription {
|
||||||
|
valptr := atomic.LoadPointer(&mg.serviceptr)
|
||||||
|
return (*serviceDescription)(valptr)
|
||||||
|
}
|
||||||
|
|
||||||
func (mg *Maingate) Destructor() {
|
func (mg *Maingate) Destructor() {
|
||||||
logger.Println("maingate.Destructor")
|
logger.Println("maingate.Destructor")
|
||||||
mg.mongoClient.Close()
|
mg.mongoClient.Close()
|
||||||
@ -396,104 +280,113 @@ func (mg *Maingate) discoverOpenIdConfiguration(name string, url string) error {
|
|||||||
|
|
||||||
func (mg *Maingate) prepare(context context.Context) (err error) {
|
func (mg *Maingate) prepare(context context.Context) (err error) {
|
||||||
if err := mg.discoverOpenIdConfiguration(AuthPlatformMicrosoft, "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"); err != nil {
|
if err := mg.discoverOpenIdConfiguration(AuthPlatformMicrosoft, "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
if err := mg.discoverOpenIdConfiguration("google", "https://accounts.google.com/.well-known/openid-configuration"); err != nil {
|
if err := mg.discoverOpenIdConfiguration("google", "https://accounts.google.com/.well-known/openid-configuration"); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mg.webTemplate = make(map[string]*template.Template)
|
|
||||||
mg.webTemplate[AuthPlatformGamepot] = template.Must(template.ParseFiles("www/gamepot.html"))
|
|
||||||
|
|
||||||
// redis에서 env를 가져온 후에
|
// redis에서 env를 가져온 후에
|
||||||
mg.mongoClient, err = common.NewMongoClient(context, mg.Mongo, "maingate")
|
mg.mongoClient, err = gocommon.NewMongoClient(context, config.Mongo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionAuth, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionCouponUse, map[string]bson.D{
|
||||||
"skonly": {{Key: "sk", Value: 1}},
|
"idrounds": {{Key: "_id", Value: 1}, {Key: "rounds", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
|
||||||
"platformuid": {{Key: "platform", Value: 1}, {Key: "uid", Value: 1}},
|
"platformuid": {{Key: "platform", Value: 1}, {Key: "uid", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
|
// if err = mg.mongoClient.MakeUniqueIndices(CollectionLink, map[string]bson.D{
|
||||||
"emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}},
|
// "emailplatform": {{Key: "email", Value: 1}, {Key: "platform", Value: 1}},
|
||||||
}); err != nil {
|
// }); err != nil {
|
||||||
return err
|
// return logger.ErrorWithCallStack(err)
|
||||||
|
// }
|
||||||
|
if err = mg.mongoClient.DropIndex(CollectionLink, "emailplatform"); err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeIndices(CollectionWhitelist, map[string]bson.D{
|
if err = mg.mongoClient.MakeIndices(CollectionAccount, map[string]bson.D{
|
||||||
"service": {{Key: "service", Value: 1}},
|
"accid": {{Key: "accid", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeIndices(CollectionFile, map[string]bson.D{
|
|
||||||
"service": {{Key: "service", Value: 1}},
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionFile, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionFile, map[string]bson.D{
|
||||||
"sk": {{Key: "service", Value: 1}, {Key: "key", Value: 1}},
|
"keyonly": {{Key: "key", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = mg.mongoClient.MakeExpireIndex(CollectionAccount, int32(config.AccDelTTL)); err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = mg.mongoClient.MakeExpireIndex(CollectionLink, int32(config.AccDelTTL)); err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete대신 _ts로 expire시킴. pipeline에 삭제 알려주기 위함
|
||||||
if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil {
|
if err = mg.mongoClient.MakeExpireIndex(CollectionWhitelist, 10); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeExpireIndex(CollectionAuth, int32(mg.SessionTTL+300)); err != nil {
|
if *devflag {
|
||||||
return err
|
// 에러 체크하지 말것
|
||||||
|
mg.mongoClient.DropIndex(CollectionBlock, "codeaccid")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := mg.mongoClient.Collection(CollectionBlock).Indexes().DropOne(context, "_ts_1"); err == nil {
|
||||||
|
// 인덱스가 방금 지워졌다.
|
||||||
|
// 전체 document 제거
|
||||||
|
logger.Println(mg.mongoClient.Collection(CollectionBlock).Drop(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionBlock, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionBlock, map[string]bson.D{
|
||||||
"codeaccid": {{Key: "code", Value: 1}, {Key: "accid", Value: 1}},
|
"accidend": {{Key: "accid", Value: 1}, {Key: "end", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeExpireIndex(CollectionBlock, int32(3)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionPlatformLoginToken, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionPlatformLoginToken, map[string]bson.D{
|
||||||
"platformauthtoken": {{Key: "platform", Value: 1}, {Key: "key", Value: 1}},
|
"platformauthtoken": {{Key: "platform", Value: 1}, {Key: "key", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(mg.SessionTTL+300)); err != nil {
|
if err = mg.mongoClient.MakeExpireIndex(CollectionPlatformLoginToken, int32(config.SessionTTL+300)); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionUserToken, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionUserToken, map[string]bson.D{
|
||||||
"platformusertoken": {{Key: "platform", Value: 1}, {Key: "userid", Value: 1}},
|
"platformusertoken": {{Key: "platform", Value: 1}, {Key: "userid", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionGamepotUserInfo, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionGamepotUserInfo, map[string]bson.D{
|
||||||
"gamepotuserid": {{Key: "gamepotuserid", Value: 1}},
|
"gamepotuserid": {{Key: "gamepotuserid", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = mg.mongoClient.MakeUniqueIndices(CollectionFirebaseUserInfo, map[string]bson.D{
|
if err = mg.mongoClient.MakeUniqueIndices(CollectionFirebaseUserInfo, map[string]bson.D{
|
||||||
"firebaseuserid": {{Key: "firebaseuserid", Value: 1}},
|
"firebaseuserid": {{Key: "firebaseuserid", Value: 1}},
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mg.auths = makeAuthCollection(mg.mongoClient, time.Duration(mg.SessionTTL*int64(time.Second)))
|
mg.sessionProvider, err = session.NewProviderWithConfig(context, config.SessionConfig)
|
||||||
|
if err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
var preall []struct {
|
var preall []struct {
|
||||||
Link string `bson:"link"`
|
Link string `bson:"link"`
|
||||||
@ -502,7 +395,7 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
|
|||||||
if err = mg.mongoClient.FindAllAs(CollectionFile, nil, &preall, options.Find().SetProjection(bson.M{
|
if err = mg.mongoClient.FindAllAs(CollectionFile, nil, &preall, options.Find().SetProjection(bson.M{
|
||||||
"link": 1,
|
"link": 1,
|
||||||
})); err != nil {
|
})); err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pre := range preall {
|
for _, pre := range preall {
|
||||||
@ -512,64 +405,112 @@ func (mg *Maingate) prepare(context context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
logger.Println("saving files :", pre.Link)
|
logger.Println("saving files :", pre.Link)
|
||||||
|
|
||||||
var fulldoc fileDocumentDesc
|
var fulldoc FileDocumentDesc
|
||||||
err = mg.mongoClient.FindOneAs(CollectionFile, bson.M{
|
err = mg.mongoClient.FindOneAs(CollectionFile, bson.M{
|
||||||
"_id": pre.Id,
|
"_id": pre.Id,
|
||||||
}, &fulldoc)
|
}, &fulldoc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
err = fulldoc.save()
|
err = fulldoc.Save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go watchAuthCollection(context, mg.auths, mg.mongoClient)
|
|
||||||
go mg.watchWhitelistCollection(context)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func whitelistKey(email string) string {
|
var portptr = flagx.Int("port", 80, "")
|
||||||
if strings.HasPrefix(email, "*@") {
|
|
||||||
// 도메인 전체 허용
|
|
||||||
return email[2:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return email
|
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) error {
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMux, prefix string) error {
|
|
||||||
var allServices []*serviceDescription
|
var allServices []*serviceDescription
|
||||||
logger.Println(CollectionService)
|
if err := mg.mongoClient.AllAs(CollectionService, &allServices, options.Find().SetReturnKey(false)); err != nil {
|
||||||
if err := mg.mongoClient.FindAllAs(CollectionService, bson.M{}, &allServices, options.Find().SetReturnKey(false)); err != nil {
|
return logger.ErrorWithCallStack(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, service := range allServices {
|
if len(allServices) > 0 {
|
||||||
if err := service.prepare(mg); err != nil {
|
only := allServices[0]
|
||||||
return err
|
only.prepare(mg)
|
||||||
|
only.mustUseChecksum = config.MustUseChecksum
|
||||||
|
|
||||||
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(only))
|
||||||
|
} else {
|
||||||
|
empty := serviceDescription{
|
||||||
|
Id: primitive.NewObjectID(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if *devflag {
|
||||||
|
addrs, err := net.InterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
|
}
|
||||||
|
ipaddr := "127.0.0.1"
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||||
|
if ipnet.IP.To4() != nil && ipnet.IP.IsPrivate() {
|
||||||
|
ipaddr = ipnet.IP.String()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Println("RegisterHandlers...")
|
empty.Divisions = map[string]*Division{
|
||||||
|
"default": {
|
||||||
|
DivisionForUser: DivisionForUser{
|
||||||
|
Priority: 0,
|
||||||
|
State: DivisionState_FullOpen,
|
||||||
|
},
|
||||||
|
|
||||||
mg.services.init(allServices)
|
Urls: bson.M{
|
||||||
for _, service := range allServices {
|
"warehouse": fmt.Sprintf("http://%s:%d/warehouse", ipaddr, *portptr),
|
||||||
if service.Closed {
|
},
|
||||||
continue
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Println("ServiceCode:", service.ServiceCode)
|
empty.prepare(mg)
|
||||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, service.ServiceCode, "/"), service)
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&empty))
|
||||||
|
|
||||||
|
filter := bson.M{"_id": empty.Id}
|
||||||
|
_, _, err := mg.mongoClient.Update(CollectionService, filter, bson.M{
|
||||||
|
"$set": &empty,
|
||||||
|
}, options.Update().SetUpsert(true))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "api", "/"), mg.api)
|
if *devflag {
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "query", "/"), mg.query)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "/"), func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// mg.service()를 요청마다 불러야 함
|
||||||
|
mg.service().serveHTTP_dev(w, r)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
pattern := gocommon.MakeHttpHandlerPattern(prefix, "/")
|
||||||
|
logger.Println("pattern registered :", pattern)
|
||||||
|
serveMux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// mg.service()를 요청마다 불러야 함
|
||||||
|
mg.service().serveHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "api/"), mg.api)
|
||||||
|
|
||||||
configraw, _ := json.Marshal(mg.maingateConfig)
|
configraw, _ := json.Marshal(config)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) {
|
var convertedConfig map[string]any
|
||||||
|
if err := json.Unmarshal(configraw, &convertedConfig); err != nil {
|
||||||
|
return logger.ErrorWithCallStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "config"), func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer func() {
|
||||||
|
s := recover()
|
||||||
|
if s != nil {
|
||||||
|
logger.Error(s)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if !*devflag {
|
||||||
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
||||||
if len(apitoken) == 0 {
|
if len(apitoken) == 0 {
|
||||||
logger.Println("MG-X-API-TOKEN is missing")
|
logger.Println("MG-X-API-TOKEN is missing")
|
||||||
@ -577,49 +518,63 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, exists := mg.apiTokenToService.get(apitoken)
|
apitokenObj, _ := primitive.ObjectIDFromHex(apitoken)
|
||||||
if !exists {
|
if mg.service().isValidToken(apitokenObj) {
|
||||||
logger.Println("MG-X-API-TOKEN is invalid :", apitoken)
|
convertedConfig["divisions"] = mg.service().Divisions
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
}
|
||||||
return
|
} else {
|
||||||
|
convertedConfig["divisions"] = mg.service().Divisions
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(configraw)
|
enc := json.NewEncoder(w)
|
||||||
|
enc.Encode(convertedConfig)
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := os.MkdirAll("static", os.ModePerm); err != nil {
|
if err := os.MkdirAll("static", os.ModePerm); err != nil {
|
||||||
// 일반 엔드유저한테 오픈할 static 페이지
|
// 일반 엔드유저한테 오픈할 static 페이지
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fsx := http.FileServer(http.Dir("./console"))
|
cfsx := http.FileServer(http.Dir("console"))
|
||||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, "console", "/"), http.StripPrefix("/console/", fsx))
|
pattern := gocommon.MakeHttpHandlerPattern(prefix, "console", "/")
|
||||||
|
serveMux.Handle(pattern, http.StripPrefix(pattern, cfsx))
|
||||||
|
logger.Println("maingate console registered :", pattern)
|
||||||
|
|
||||||
ssx := http.FileServer(http.Dir("./static"))
|
staticfs := http.FileServer(http.Dir("static"))
|
||||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, "static", "/"), http.StripPrefix("/static/", ssx))
|
pattern = gocommon.MakeHttpHandlerPattern(prefix, "static", "/")
|
||||||
|
serveMux.Handle(pattern, http.StripPrefix(pattern, staticfs))
|
||||||
|
logger.Println("maingate static registered :", pattern)
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGoogle), mg.platform_google_get_login_url)
|
fbafs := http.FileServer(http.Dir("fba"))
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGoogle), mg.platform_google_authorize)
|
pattern = gocommon.MakeHttpHandlerPattern(prefix, "fba", "/")
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformGoogle), mg.platform_google_authorize_result)
|
serveMux.Handle(pattern, http.StripPrefix(pattern, fbafs))
|
||||||
|
logger.Println("google_analytics static registered :", pattern)
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformMicrosoft), mg.platform_microsoft_get_login_url)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "fba", "fb-ga.min.js"), mg.google_analytics_js)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformMicrosoft), mg.platform_microsoft_authorize)
|
logger.Println("google_analytics.js static registered :", pattern)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformMicrosoft), mg.platform_microsoft_authorize_result)
|
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformTwitter), mg.platform_twitter_get_login_url)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGoogle), mg.platform_google_get_login_url)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformTwitter), mg.platform_twitter_authorize)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGoogle), mg.platform_google_authorize)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformTwitter), mg.platform_twitter_authorize_result)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformGoogle), mg.platform_google_authorize_result)
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformApple), mg.platform_apple_get_login_url)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformMicrosoft), mg.platform_microsoft_get_login_url)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformApple), mg.platform_apple_authorize)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformMicrosoft), mg.platform_microsoft_authorize)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformApple), mg.platform_apple_authorize_result)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformMicrosoft), mg.platform_microsoft_authorize_result)
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformGamepot), mg.platform_gamepot_get_login_url)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformTwitter), mg.platform_twitter_get_login_url)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformGamepot), mg.platform_gamepot_authorize)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformTwitter), mg.platform_twitter_authorize)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformGamepot), mg.platform_gamepot_authorize_sdk)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformTwitter), mg.platform_twitter_authorize_result)
|
||||||
|
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_get_login_url)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformApple), mg.platform_apple_get_login_url)
|
||||||
serveMux.HandleFunc(common.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_authorize_sdk)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize", AuthPlatformApple), mg.platform_apple_authorize)
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_result", AuthPlatformApple), mg.platform_apple_authorize_result)
|
||||||
|
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "request_login_url", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_get_login_url)
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformFirebaseAuth), mg.platform_firebaseauth_authorize_sdk)
|
||||||
|
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformSteamSDK), mg.platform_steamsdk_authorize)
|
||||||
|
|
||||||
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "authorize_sdk", AuthPlatformHybeim), mg.platform_hybeim_authorize)
|
||||||
|
|
||||||
go mg.watchServiceCollection(ctx, serveMux, prefix)
|
go mg.watchServiceCollection(ctx, serveMux, prefix)
|
||||||
go mg.watchFileCollection(ctx, serveMux, prefix)
|
go mg.watchFileCollection(ctx, serveMux, prefix)
|
||||||
@ -630,95 +585,38 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) query(w http.ResponseWriter, r *http.Request) {
|
|
||||||
defer func() {
|
|
||||||
s := recover()
|
|
||||||
if s != nil {
|
|
||||||
logger.Error(s)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
io.Copy(io.Discard, r.Body)
|
|
||||||
r.Body.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
queryvals := r.URL.Query()
|
|
||||||
sk := queryvals.Get("sk")
|
|
||||||
|
|
||||||
if len(sk) == 0 {
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
info := mg.auths.Find(sk)
|
|
||||||
if info == nil {
|
|
||||||
logger.Println("session key is not valid :", sk)
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apitoken := r.Header.Get("MG-X-API-TOKEN")
|
|
||||||
if len(apitoken) == 0 {
|
|
||||||
logger.Println("MG-X-API-TOKEN is missing")
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
servicecode, exists := mg.apiTokenToService.get(apitoken)
|
|
||||||
if !exists {
|
|
||||||
logger.Println("MG-X-API-TOKEN is invalid :", apitoken)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.ServiceCode != servicecode {
|
|
||||||
logger.Println("session is not for this service :", info.ServiceCode, servicecode)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bt, _ := json.Marshal(info)
|
|
||||||
w.Write(bt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) GeneratePlatformLoginNonceKey() string {
|
func (mg *Maingate) GeneratePlatformLoginNonceKey() string {
|
||||||
const allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
const allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
b := make([]byte, 52)
|
b := make([]byte, 52)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
b[i] = allowed[rand.Intn(len(allowed))]
|
b[i] = allowed[r.Intn(len(allowed))]
|
||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) GetUserBrowserInfo(r *http.Request) (string, error) {
|
func (mg *Maingate) GetUserBrowserInfo(r *http.Request) (string, error) {
|
||||||
//=========== 브라우저 검증쪽은 앞으로 빼자
|
//=========== 브라우저 검증쪽은 앞으로 빼자
|
||||||
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
// host, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
logger.Error("Error: RemoteAddr Split Error :", err)
|
// logger.Error("Error: RemoteAddr Split Error :", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
cookie, err := r.Cookie("ActionSquareSessionExtraInfo")
|
cookie, err := r.Cookie("ActionSquareSessionExtraInfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
requestinfo := fmt.Sprintf("%s_%s", cookie.Value, host)
|
//requestinfo := fmt.Sprintf("%s_%s", cookie.Value, host) //-- RemoteAddr체크는 로드밸런서 IP 찍히는 문제 때문에 제외한다.
|
||||||
|
requestinfo := fmt.Sprintf("%s_", cookie.Value)
|
||||||
return requestinfo, nil
|
return requestinfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) setUserToken(info usertokeninfo) error {
|
func (mg *Maingate) setUserToken(info usertokeninfo) error {
|
||||||
|
|
||||||
mg.mongoClient.Delete(CollectionUserToken, bson.M{
|
|
||||||
"platform": info.platform,
|
|
||||||
"userid": info.userid,
|
|
||||||
})
|
|
||||||
_, _, err := mg.mongoClient.Update(CollectionUserToken, bson.M{
|
_, _, err := mg.mongoClient.Update(CollectionUserToken, bson.M{
|
||||||
"_id": primitive.NewObjectID(),
|
|
||||||
}, bson.M{
|
|
||||||
"$setOnInsert": bson.M{
|
|
||||||
"platform": info.platform,
|
"platform": info.platform,
|
||||||
"userid": info.userid,
|
"userid": info.userid,
|
||||||
|
}, bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
"token": info.token,
|
"token": info.token,
|
||||||
"secret": info.secret,
|
"secret": info.secret,
|
||||||
"brinfo": info.brinfo,
|
"brinfo": info.brinfo,
|
||||||
@ -727,7 +625,7 @@ func (mg *Maingate) setUserToken(info usertokeninfo) error {
|
|||||||
"accesstoken_expire_time": info.accesstoken_expire_time,
|
"accesstoken_expire_time": info.accesstoken_expire_time,
|
||||||
},
|
},
|
||||||
}, options.Update().SetUpsert(true))
|
}, options.Update().SetUpsert(true))
|
||||||
return err
|
return logger.ErrorWithCallStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo string) (usertokeninfo, error) {
|
func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo string) (usertokeninfo, error) {
|
||||||
@ -737,19 +635,22 @@ func (mg *Maingate) getUserTokenWithCheck(platform string, userid string, brinfo
|
|||||||
found, err := mg.mongoClient.FindOne(CollectionUserToken, bson.M{
|
found, err := mg.mongoClient.FindOne(CollectionUserToken, bson.M{
|
||||||
"platform": platform,
|
"platform": platform,
|
||||||
"userid": userid,
|
"userid": userid,
|
||||||
"brinfo": brinfo,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return info, err
|
return info, err
|
||||||
}
|
}
|
||||||
if found == nil {
|
if found == nil {
|
||||||
return info, errors.New("user token not found: " + platform + " / " + userid + " / " + brinfo)
|
return info, errors.New("user token not found :" + platform + " / " + userid + " / " + brinfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
if found["brinfo"].(string) != brinfo {
|
||||||
|
return info, errors.New("user brinfo is different :" + platform + " / " + userid + " / " + brinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
updatetime, ok := found["lastupdate"].(int64)
|
updatetime, ok := found["lastupdate"].(int64)
|
||||||
|
|
||||||
if !ok || time.Now().Unix()-updatetime < mg.maingateConfig.Autologin_ttl {
|
if !ok || time.Now().Unix()-updatetime < config.Autologin_ttl {
|
||||||
info.platform = platform
|
info.platform = platform
|
||||||
info.userid = userid
|
info.userid = userid
|
||||||
info.brinfo = brinfo
|
info.brinfo = brinfo
|
||||||
@ -796,8 +697,10 @@ func (mg *Maingate) updateUserinfo(info usertokeninfo) (bool, string, string) {
|
|||||||
success, userid, email = mg.platform_microsoft_getuserinfo(info)
|
success, userid, email = mg.platform_microsoft_getuserinfo(info)
|
||||||
case AuthPlatformGoogle:
|
case AuthPlatformGoogle:
|
||||||
success, userid, email = mg.platform_google_getuserinfo(info)
|
success, userid, email = mg.platform_google_getuserinfo(info)
|
||||||
case AuthPlatformGamepot:
|
case AuthPlatformSteamSDK:
|
||||||
success, userid, email = mg.platform_gamepot_getuserinfo(info)
|
success, userid, email = mg.platform_steamsdk_getuserinfo(info)
|
||||||
|
case AuthPlatformHybeim:
|
||||||
|
success, userid, email = mg.platform_hybeim_getuserinfo(info)
|
||||||
case AuthPlatformFirebaseAuth:
|
case AuthPlatformFirebaseAuth:
|
||||||
success, userid, email = mg.platform_firebase_getuserinfo(info)
|
success, userid, email = mg.platform_firebase_getuserinfo(info)
|
||||||
}
|
}
|
||||||
@ -1007,3 +910,22 @@ func JWTparseCode(keyurl string, code string) (string, string, string) {
|
|||||||
//--- nonce 체크 필요하다.
|
//--- nonce 체크 필요하다.
|
||||||
return claims["sub"].(string), email, nonce
|
return claims["sub"].(string), email, nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mg *Maingate) google_analytics_js(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fgaconfig := Firebase_Google_Analytics_JS_SDK_Config{
|
||||||
|
FGA_apiKey: config.FGA_apiKey,
|
||||||
|
FGA_authDomain: config.FGA_authDomain,
|
||||||
|
FGA_databaseURL: config.FGA_databaseURL,
|
||||||
|
FGA_projectId: config.FGA_projectId,
|
||||||
|
FGA_storageBucket: config.FGA_storageBucket,
|
||||||
|
FGA_messagingSenderId: config.FGA_messagingSenderId,
|
||||||
|
FGA_appId: config.FGA_appId,
|
||||||
|
FGA_measurementId: config.FGA_measurementId,
|
||||||
|
}
|
||||||
|
parsedTemplate, _ := template.ParseFiles("template/fb-ga.min.js")
|
||||||
|
err := parsedTemplate.Execute(w, fgaconfig)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Error executing template :", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -95,8 +95,8 @@ func (mg *Maingate) platform_apple_get_login_url(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.AppleCientId)
|
params.Add("client_id", config.AppleCientId)
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformApple)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformApple)
|
||||||
|
|
||||||
params.Add("response_type", "code id_token")
|
params.Add("response_type", "code id_token")
|
||||||
params.Add("scope", "name email")
|
params.Add("scope", "name email")
|
||||||
@ -146,7 +146,7 @@ func (mg *Maingate) platform_apple_authorize(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
|
||||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformApple, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *http.Request) {
|
func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -208,17 +208,17 @@ func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *ht
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the client secret used to authenticate with Apple's validation servers
|
// Generate the client secret used to authenticate with Apple's validation servers
|
||||||
secret, err := generateClientSecret(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
|
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error generating secret: ", err)
|
logger.Error("error generating secret: ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vReq := Apple_WebValidationTokenRequest{
|
vReq := Apple_WebValidationTokenRequest{
|
||||||
ClientID: mg.AppleServiceId,
|
ClientID: config.AppleServiceId,
|
||||||
ClientSecret: secret,
|
ClientSecret: secret,
|
||||||
Code: code,
|
Code: code,
|
||||||
RedirectURI: mg.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service
|
RedirectURI: config.RedirectBaseUrl + "/authorize/" + AuthPlatformApple, // This URL must be validated with apple in your service
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp Apple_ValidationResponse
|
var resp Apple_ValidationResponse
|
||||||
@ -268,14 +268,14 @@ func (mg *Maingate) platform_apple_authorize_result(w http.ResponseWriter, r *ht
|
|||||||
|
|
||||||
func (mg *Maingate) platform_apple_getuserinfo(refreshToken string) (bool, string, string) {
|
func (mg *Maingate) platform_apple_getuserinfo(refreshToken string) (bool, string, string) {
|
||||||
//=================================RefreshToken을 사용해서 정보 가져 온다. 이미 인증된 사용자의 업데이트 목적
|
//=================================RefreshToken을 사용해서 정보 가져 온다. 이미 인증된 사용자의 업데이트 목적
|
||||||
secret, err := generateClientSecret(mg.ApplePrivateKey, mg.AppleTeamId, mg.AppleServiceId, mg.AppleKeyId)
|
secret, err := generateClientSecret(config.ApplePrivateKey, config.AppleTeamId, config.AppleServiceId, config.AppleKeyId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error generating secret: ", err)
|
logger.Error("error generating secret: ", err)
|
||||||
return false, "", ""
|
return false, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
vReqRefreshToken := Apple_WebRefreshTokenRequest{
|
vReqRefreshToken := Apple_WebRefreshTokenRequest{
|
||||||
ClientID: mg.AppleServiceId,
|
ClientID: config.AppleServiceId,
|
||||||
ClientSecret: secret,
|
ClientSecret: secret,
|
||||||
RefreshToken: refreshToken,
|
RefreshToken: refreshToken,
|
||||||
}
|
}
|
||||||
@ -289,7 +289,7 @@ func (mg *Maingate) platform_apple_getuserinfo(refreshToken string) (bool, strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if respReferesh.Error != "" {
|
if respReferesh.Error != "" {
|
||||||
logger.Error("apple returned an error: %s - %s\n", respReferesh.Error, respReferesh.ErrorDescription)
|
logger.Errorf("apple returned an error: %s - %s\n", respReferesh.Error, respReferesh.ErrorDescription)
|
||||||
return false, "", ""
|
return false, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package core
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -146,6 +147,11 @@ func (mg *Maingate) platform_firebaseauth_authorize_sdk(w http.ResponseWriter, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, memberId, nickname, provider, providerId, email, photourl, phonenumber string) (bool, string) {
|
func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, memberId, nickname, provider, providerId, email, photourl, phonenumber string) (bool, string) {
|
||||||
|
if mg.firebase == nil {
|
||||||
|
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
|
||||||
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
|
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
|
||||||
"platform": AuthPlatformFirebaseAuth,
|
"platform": AuthPlatformFirebaseAuth,
|
||||||
@ -188,7 +194,7 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
|
|||||||
return false, ""
|
return false, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, code)
|
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error verifying ID token:", err)
|
log.Println("error verifying ID token:", err)
|
||||||
return false, ""
|
return false, ""
|
||||||
@ -242,6 +248,10 @@ func (mg *Maingate) platform_firebaseauth_authorize_raw(w http.ResponseWriter, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, string, string) {
|
func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, string, string) {
|
||||||
|
if mg.firebase == nil {
|
||||||
|
logger.Println("mg.firebase is nil. check 'firebase_admin_sdk_credentialfile' config or 'authtype' parameter")
|
||||||
|
return false, "", ""
|
||||||
|
}
|
||||||
|
|
||||||
found, err := mg.mongoClient.FindOne(CollectionFirebaseUserInfo, bson.M{
|
found, err := mg.mongoClient.FindOne(CollectionFirebaseUserInfo, bson.M{
|
||||||
"firebaseuserid": info.userid,
|
"firebaseuserid": info.userid,
|
||||||
@ -256,13 +266,16 @@ func (mg *Maingate) platform_firebase_getuserinfo(info usertokeninfo) (bool, str
|
|||||||
return false, "", ""
|
return false, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = mg.firebaseAppClient.VerifyIDToken(mg.firebaseAppContext, info.token)
|
_, err = mg.firebase.firebaseAppClient.VerifyIDToken(mg.firebase.firebaseAppContext, info.token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error verifying ID token:", err)
|
log.Println("error verifying ID token:", err)
|
||||||
return false, "", ""
|
return false, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
tempEmail := found["firebaseemail"].(string)
|
tempEmail := found["firebaseemail"].(string)
|
||||||
|
if found["firebaseprovider"].(string) == "guest" {
|
||||||
|
tempEmail = fmt.Sprintf("%s@guest.flag", info.userid)
|
||||||
|
}
|
||||||
|
|
||||||
return true, info.userid, tempEmail
|
return true, info.userid, tempEmail
|
||||||
|
|
||||||
|
|||||||
@ -1,344 +0,0 @@
|
|||||||
package core
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GamepotTemplate struct {
|
|
||||||
RedirectBaseUrl string
|
|
||||||
State string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Gamepot_LoginValidationResponse struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
Status int `json:"status"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) platform_gamepot_get_login_url(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
browserinfo, err := mg.GetUserBrowserInfo(r)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
existid := r.URL.Query().Get("existid")
|
|
||||||
withSDK := r.URL.Query().Get("withSDK")
|
|
||||||
|
|
||||||
//fmt.Println("existid =>", existid)
|
|
||||||
if existid != "" {
|
|
||||||
//기존 계정이 있는 경우에는 그 계정 부터 조회한다.
|
|
||||||
info, err := mg.getUserTokenWithCheck(AuthPlatformGamepot, existid, browserinfo)
|
|
||||||
if err == nil {
|
|
||||||
if info.token != "" {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Add("id", existid)
|
|
||||||
params.Add("authtype", AuthPlatformGamepot)
|
|
||||||
if withSDK == "1" {
|
|
||||||
w.Write([]byte("?" + params.Encode()))
|
|
||||||
} else {
|
|
||||||
http.Redirect(w, r, "actionsquare://login?"+params.Encode(), http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionkey := mg.GeneratePlatformLoginNonceKey()
|
|
||||||
nonce := mg.GeneratePlatformLoginNonceKey()
|
|
||||||
|
|
||||||
mg.mongoClient.Delete(CollectionPlatformLoginToken, bson.M{
|
|
||||||
"platform": AuthPlatformGamepot,
|
|
||||||
"key": sessionkey,
|
|
||||||
})
|
|
||||||
|
|
||||||
_, _, err = mg.mongoClient.Update(CollectionPlatformLoginToken, bson.M{
|
|
||||||
"_id": primitive.NewObjectID(),
|
|
||||||
}, bson.M{
|
|
||||||
"$setOnInsert": bson.M{
|
|
||||||
"platform": AuthPlatformGamepot,
|
|
||||||
"key": sessionkey,
|
|
||||||
"nonce": nonce,
|
|
||||||
"brinfo": browserinfo,
|
|
||||||
},
|
|
||||||
}, options.Update().SetUpsert(true))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// set cookie for storing token
|
|
||||||
cookie := http.Cookie{
|
|
||||||
Name: "LoginFlowContext_SessionKey",
|
|
||||||
Value: sessionkey,
|
|
||||||
Expires: time.Now().Add(1 * time.Hour),
|
|
||||||
//SameSite: http.SameSiteStrictMode,
|
|
||||||
SameSite: http.SameSiteLaxMode,
|
|
||||||
// HttpOnly: false,
|
|
||||||
Secure: true,
|
|
||||||
Path: "/",
|
|
||||||
}
|
|
||||||
http.SetCookie(w, &cookie)
|
|
||||||
|
|
||||||
if withSDK == "1" {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Add("nonce", nonce)
|
|
||||||
w.Write([]byte("?" + params.Encode()))
|
|
||||||
} else {
|
|
||||||
var templateVar GamepotTemplate
|
|
||||||
templateVar.RedirectBaseUrl = mg.RedirectBaseUrl
|
|
||||||
templateVar.State = nonce
|
|
||||||
mg.webTemplate[AuthPlatformGamepot].Execute(w, templateVar)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) platform_gamepot_authorize(w http.ResponseWriter, r *http.Request) {
|
|
||||||
defer r.Body.Close()
|
|
||||||
|
|
||||||
brinfo, err := mg.GetUserBrowserInfo(r)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cookie, err := r.Cookie("LoginFlowContext_SessionKey")
|
|
||||||
if err != nil {
|
|
||||||
logger.Println("Session not found", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.ParseForm()
|
|
||||||
|
|
||||||
code := r.Form.Get("code")
|
|
||||||
state := r.Form.Get("state")
|
|
||||||
|
|
||||||
gamepotmemberId := r.Form.Get("id")
|
|
||||||
gamepotnickname := r.Form.Get("nickname")
|
|
||||||
gamepotprovider := r.Form.Get("provider")
|
|
||||||
gamepotproviderId := r.Form.Get("providerId")
|
|
||||||
// gamepotverify := r.Form.Get("verify")
|
|
||||||
// gamepotagree := r.Form.Get("agree")
|
|
||||||
|
|
||||||
bSuccess, Result := mg.platform_gamepot_authorize_raw(w, brinfo, code, state, cookie.Value, gamepotmemberId, gamepotnickname, gamepotprovider, gamepotproviderId)
|
|
||||||
|
|
||||||
if bSuccess {
|
|
||||||
http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type GamePotSDKAuthInfo struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
State string `json:"state"`
|
|
||||||
MemberId string `json:"id"`
|
|
||||||
Nickname string `json:"nickname"`
|
|
||||||
Provider string `json:"provider"`
|
|
||||||
ProviderId string `json:"providerId"`
|
|
||||||
// Verify string `json:"verify"`
|
|
||||||
// Agree string `json:"agree"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) platform_gamepot_authorize_sdk(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
defer r.Body.Close()
|
|
||||||
|
|
||||||
brinfo, err := mg.GetUserBrowserInfo(r)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
logger.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cookie, err := r.Cookie("LoginFlowContext_SessionKey")
|
|
||||||
if err != nil {
|
|
||||||
logger.Println("Session not found", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var authinfo GamePotSDKAuthInfo
|
|
||||||
|
|
||||||
err = json.NewDecoder(r.Body).Decode(&authinfo)
|
|
||||||
if err != nil {
|
|
||||||
logger.Println("authinfo decoding fail:", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bSuccess, Result := mg.platform_gamepot_authorize_raw(w, brinfo, authinfo.Code, authinfo.State,
|
|
||||||
cookie.Value, authinfo.MemberId, authinfo.Nickname, authinfo.Provider, authinfo.ProviderId)
|
|
||||||
|
|
||||||
if bSuccess {
|
|
||||||
w.Write([]byte("?" + Result))
|
|
||||||
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) platform_gamepot_authorize_raw(w http.ResponseWriter, brinfo, code, state, cookieSessionKey, gamepotmemberId, gamepotnickname, gamepotprovider, gamepotproviderId string) (bool, string) {
|
|
||||||
|
|
||||||
found, err := mg.mongoClient.FindOne(CollectionPlatformLoginToken, bson.M{
|
|
||||||
"platform": AuthPlatformGamepot,
|
|
||||||
"key": cookieSessionKey,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
logger.Println("LoginFlowContext_SessionKey find key :", err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if found == nil {
|
|
||||||
logger.Println("LoginFlowContext_SessionKey not found")
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if cookieSessionKey != found["key"] {
|
|
||||||
logger.Println("LoginFlowContext_SessionKey key not match")
|
|
||||||
logger.Println(cookieSessionKey)
|
|
||||||
logger.Println(found["key"])
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if state != found["nonce"] {
|
|
||||||
logger.Println("LoginFlowContext_SessionKey nonce not match")
|
|
||||||
logger.Println(state)
|
|
||||||
logger.Println(found["nonce"])
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if brinfo != found["brinfo"] { //-- 로그인 시작점과 인증점의 브라우저 혹은 접속지 정보가 다르다?
|
|
||||||
logger.Println("LoginFlowContext_SessionKey brinfo not match ")
|
|
||||||
logger.Println(brinfo)
|
|
||||||
logger.Println(found["brinfo"])
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
//=================
|
|
||||||
params := url.Values{}
|
|
||||||
params.Add("projectId", mg.GamepotProjectId)
|
|
||||||
params.Add("memberId", gamepotmemberId)
|
|
||||||
params.Add("token", code)
|
|
||||||
|
|
||||||
var respLoginCheck Gamepot_LoginValidationResponse
|
|
||||||
content := params.Encode()
|
|
||||||
resp, _ := http.Post(mg.GamepotLoginCheckAPIURL, "application/json", bytes.NewBuffer([]byte(content)))
|
|
||||||
if resp != nil {
|
|
||||||
body, _ := io.ReadAll(resp.Body)
|
|
||||||
json.Unmarshal(body, &respLoginCheck)
|
|
||||||
} else {
|
|
||||||
logger.Println("gamepot logincheck fail.")
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// fmt.Println("==============================")
|
|
||||||
// fmt.Println("respLoginCheck.Status:", respLoginCheck.Status)
|
|
||||||
// fmt.Println("respLoginCheck.Message:", respLoginCheck.Message)
|
|
||||||
// fmt.Println("==============================")
|
|
||||||
|
|
||||||
if respLoginCheck.Status != 0 {
|
|
||||||
logger.Errorf("gamepot login fail:", respLoginCheck.Message)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
|
|
||||||
|
|
||||||
if gamepotmemberId != "" && gamepotprovider != "" && gamepotproviderId != "" {
|
|
||||||
var info usertokeninfo
|
|
||||||
info.platform = AuthPlatformGamepot
|
|
||||||
info.userid = gamepotmemberId
|
|
||||||
//== memberid 제외하고는 모두 client로 부터 온 값이기 때문에 유효성이 확인된 값이 아니다. 하지만, 참조용으로 사용은 한다.
|
|
||||||
// 정확한 정보는 gamepotid를 gamepot dashboard에서 조회해서 확인 할 수 밖에 없다.
|
|
||||||
info.token = gamepotprovider + "-" + gamepotproviderId
|
|
||||||
info.brinfo = brinfo
|
|
||||||
info.accesstoken = ""
|
|
||||||
info.accesstoken_expire_time = acceestoken_expire_time
|
|
||||||
mg.setUserToken(info)
|
|
||||||
|
|
||||||
mg.mongoClient.Delete(CollectionGamepotUserInfo, bson.M{
|
|
||||||
"gamepotuserid": info.userid,
|
|
||||||
})
|
|
||||||
|
|
||||||
_, _, err := mg.mongoClient.Update(CollectionGamepotUserInfo, bson.M{
|
|
||||||
"_id": primitive.NewObjectID(),
|
|
||||||
}, bson.M{
|
|
||||||
"$setOnInsert": bson.M{
|
|
||||||
"gamepotuserid": gamepotmemberId,
|
|
||||||
"gamepotnickname": gamepotnickname,
|
|
||||||
"gamepotprovider": gamepotprovider,
|
|
||||||
"gamepotproviderId": gamepotproviderId,
|
|
||||||
// "gamepotverify": gamepotverify,
|
|
||||||
// "gamepotagree": gamepotagree,
|
|
||||||
"updatetime": time.Now(),
|
|
||||||
},
|
|
||||||
}, options.Update().SetUpsert(true))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Add("id", gamepotmemberId)
|
|
||||||
params.Add("authtype", AuthPlatformGamepot)
|
|
||||||
return true, params.Encode()
|
|
||||||
}
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) platform_gamepot_getuserinfo(info usertokeninfo) (bool, string, string) {
|
|
||||||
|
|
||||||
found, err := mg.mongoClient.FindOne(CollectionGamepotUserInfo, bson.M{
|
|
||||||
"gamepotuserid": info.userid,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
logger.Error(err)
|
|
||||||
return false, "", ""
|
|
||||||
}
|
|
||||||
if found == nil {
|
|
||||||
logger.Error(errors.New("gamepot info not found: " + info.userid))
|
|
||||||
return false, "", ""
|
|
||||||
}
|
|
||||||
|
|
||||||
gamepotprovider := found["gamepotprovider"].(string)
|
|
||||||
gamepotproviderId := found["gamepotproviderId"].(string)
|
|
||||||
|
|
||||||
if gamepotprovider+"-"+gamepotproviderId != info.token {
|
|
||||||
logger.Println("gamepot info not match..") //-- token은 플랫폼종류+플랫폼ID로 구성했는데... 검증할 방법이 없어서 client로 부터 온값을 쓴다. 그래도 유저가 조작하지 않는 이상 일치해야 된다.
|
|
||||||
logger.Println(info.token)
|
|
||||||
logger.Println(gamepotprovider + "-" + gamepotproviderId)
|
|
||||||
return false, "", ""
|
|
||||||
}
|
|
||||||
|
|
||||||
tempEmail := info.userid + "@gamepot" //-- 게임팟은 email을 안줘서 일단 gamepotid기준으로 임시값을 할당한다.
|
|
||||||
|
|
||||||
return true, info.userid, tempEmail
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -84,9 +84,9 @@ func (mg *Maingate) platform_google_get_login_url(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.GoogleClientId)
|
params.Add("client_id", config.GoogleClientId)
|
||||||
params.Add("response_type", "code")
|
params.Add("response_type", "code")
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||||
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
|
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
|
||||||
params.Add("access_type", "offline")
|
params.Add("access_type", "offline")
|
||||||
params.Add("prompt", "consent")
|
params.Add("prompt", "consent")
|
||||||
@ -140,7 +140,7 @@ func (mg *Maingate) platform_google_authorize(w http.ResponseWriter, r *http.Req
|
|||||||
}
|
}
|
||||||
http.SetCookie(w, &cookie2)
|
http.SetCookie(w, &cookie2)
|
||||||
|
|
||||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformGoogle, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *http.Request) {
|
func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -211,9 +211,9 @@ func (mg *Maingate) platform_google_authorize_result(w http.ResponseWriter, r *h
|
|||||||
|
|
||||||
//=================
|
//=================
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.GoogleClientId)
|
params.Add("client_id", config.GoogleClientId)
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||||
params.Add("client_secret", mg.GoogleClientSecret)
|
params.Add("client_secret", config.GoogleClientSecret)
|
||||||
params.Add("code", code)
|
params.Add("code", code)
|
||||||
params.Add("grant_type", "authorization_code")
|
params.Add("grant_type", "authorization_code")
|
||||||
|
|
||||||
@ -285,9 +285,9 @@ func (mg *Maingate) platform_google_getuserinfo(info usertokeninfo) (bool, strin
|
|||||||
if time.Now().Unix() > info.accesstoken_expire_time {
|
if time.Now().Unix() > info.accesstoken_expire_time {
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.GoogleClientId)
|
params.Add("client_id", config.GoogleClientId)
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformGoogle)
|
||||||
params.Add("client_secret", mg.GoogleClientSecret)
|
params.Add("client_secret", config.GoogleClientSecret)
|
||||||
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
|
params.Add("scope", "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email")
|
||||||
params.Add("refresh_token", info.token)
|
params.Add("refresh_token", info.token)
|
||||||
params.Add("grant_type", "refresh_token")
|
params.Add("grant_type", "refresh_token")
|
||||||
|
|||||||
198
core/platformhybeim.go
Normal file
198
core/platformhybeim.go
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HybeImSDKAuthInfo struct {
|
||||||
|
UserHybeimid string `json:"imid"`
|
||||||
|
UserLoginVerifyToken string `json:"loginVerifyToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HybeImSDKLoginAuthInfo struct {
|
||||||
|
ServiceId string `json:"serviceId"`
|
||||||
|
UserLoginVerifyToken string `json:"loginVerifyToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hiveim_LoginVerifyResult struct {
|
||||||
|
State string `json:"state"`
|
||||||
|
ImId string `json:"imId"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
Os string `json:"os"`
|
||||||
|
AppStore string `json:"appStore"`
|
||||||
|
UserBlockInfo []Hiveim_UserBlockInfo `json:"blocks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hiveim_UserBlockInfo struct {
|
||||||
|
BlockId int `json:"blockId"`
|
||||||
|
ReasonId int `json:"reasonId"`
|
||||||
|
BlockedAt int64 `json:"blockedAt"`
|
||||||
|
ExpireAt int64 `json:"expireAt"`
|
||||||
|
Permanent bool `json:"permanent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hiveim_LoginValidationResponse struct {
|
||||||
|
ResultCode string `json:"resultCode"`
|
||||||
|
ResultMessage string `json:"resultMessage"`
|
||||||
|
ResultData Hiveim_LoginVerifyResult `json:"resultData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mg *Maingate) platform_hybeim_authorize(w http.ResponseWriter, r *http.Request) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
brinfo, err := mg.GetUserBrowserInfo(r)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
logger.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var authinfo HybeImSDKAuthInfo
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&authinfo)
|
||||||
|
if err != nil {
|
||||||
|
logger.Println("authinfo decoding fail:", err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultcode string
|
||||||
|
var blockinfo Hiveim_UserBlockInfo
|
||||||
|
if !*noauth {
|
||||||
|
err, resultcode, blockinfo = authenticateHybeImUser(config.HybeImProjectIdstring, config.HybeImServiceIdstring, config.HybeImAccessKey, config.HybeImEndPoint, authinfo.UserHybeimid, authinfo.UserLoginVerifyToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://hybeim.gitbook.io/im-assemble/api/im-assemble-s2s-api#login-verify
|
||||||
|
// SUCCESS : 성공
|
||||||
|
// INVALID_LOGIN_VERIFY_TOKEN : login 인증 토큰 오류
|
||||||
|
// LOGIN_VERIFY_EXPIRED : login 인증 토큰 만료
|
||||||
|
// INVALID_SERVICE_ID : 유효 하지 않은 서비스 id
|
||||||
|
// WITHDRAWAL_ACCOUNT : 탈퇴 대기 상태 유저
|
||||||
|
// RELOGIN_REQUIRED : 로그인 데이터에 문제가 있어 다시 로그인 해야 되는 경우
|
||||||
|
// INTERNAL_SERVER_ERROR : 서버 오류
|
||||||
|
|
||||||
|
if err == nil && resultcode == "SUCCESS" {
|
||||||
|
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
|
||||||
|
|
||||||
|
var info usertokeninfo
|
||||||
|
info.platform = AuthPlatformHybeim
|
||||||
|
info.userid = authinfo.UserHybeimid
|
||||||
|
info.token = authinfo.UserLoginVerifyToken
|
||||||
|
info.brinfo = brinfo
|
||||||
|
//info.accesstoken = respReferesh.AccessToken
|
||||||
|
info.accesstoken_expire_time = acceestoken_expire_time
|
||||||
|
mg.setUserToken(info)
|
||||||
|
|
||||||
|
params := url.Values{}
|
||||||
|
params.Add("id", authinfo.UserHybeimid)
|
||||||
|
params.Add("authtype", AuthPlatformHybeim)
|
||||||
|
w.Write([]byte("?" + params.Encode()))
|
||||||
|
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
params := url.Values{}
|
||||||
|
params.Add("resultcode", resultcode)
|
||||||
|
if resultcode == "BLOCKED" {
|
||||||
|
blockinfoBytes, _ := json.Marshal(blockinfo)
|
||||||
|
blockinfostr := string(blockinfoBytes)
|
||||||
|
params.Add("blockinfo", blockinfostr)
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte("?" + params.Encode()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// logger.Println(err)
|
||||||
|
// http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func authenticateHybeImUser(projectid, serviceid, accesskey, endpoint, imid, UserLoginVerifyToken string) (error, string, Hiveim_UserBlockInfo) {
|
||||||
|
|
||||||
|
// endpoint
|
||||||
|
// qa = https://api-qa.pub-dev.hybegames.io
|
||||||
|
// prod = https://api.hybegames.com
|
||||||
|
|
||||||
|
verifyurl := endpoint + "/member/api-game/v1/auth/login/verify"
|
||||||
|
|
||||||
|
var param HybeImSDKLoginAuthInfo
|
||||||
|
param.UserLoginVerifyToken = UserLoginVerifyToken
|
||||||
|
param.ServiceId = serviceid
|
||||||
|
|
||||||
|
dat, err := json.Marshal(param)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var respReferesh Hiveim_LoginValidationResponse
|
||||||
|
req, err := http.NewRequest("POST", verifyurl, bytes.NewBuffer(dat))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("X-Auth-Access-Key", accesskey)
|
||||||
|
req.Header.Add("X-Req-Pjid", projectid)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
io.Copy(io.Discard, resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
var blockinfo Hiveim_UserBlockInfo
|
||||||
|
body, e := ioutil.ReadAll(resp.Body)
|
||||||
|
if e != nil {
|
||||||
|
return e, "", blockinfo
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(body, &respReferesh)
|
||||||
|
|
||||||
|
//fmt.Println(string(body))
|
||||||
|
|
||||||
|
var doc map[string]interface{}
|
||||||
|
if err := json.Unmarshal(body, &doc); err != nil {
|
||||||
|
return err, respReferesh.ResultCode, blockinfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// if respReferesh.ResultData.State != "NORMAL" {
|
||||||
|
// return errors.New("higveimSDK: State is not NORMAL"), respReferesh.ResultCode, blockinfo
|
||||||
|
// }
|
||||||
|
|
||||||
|
if respReferesh.ResultData.Provider != "STEAM" {
|
||||||
|
return errors.New("higveimSDK: Provider is not STEAM"), respReferesh.ResultCode, blockinfo
|
||||||
|
}
|
||||||
|
|
||||||
|
if respReferesh.ResultData.ImId != imid {
|
||||||
|
return errors.New("higveimSDK: ImId is not match"), respReferesh.ResultCode, blockinfo
|
||||||
|
}
|
||||||
|
|
||||||
|
if respReferesh.ResultCode == "SUCCESS" {
|
||||||
|
if respReferesh.ResultData.State == "BLOCKED" && len(respReferesh.ResultData.UserBlockInfo) > 0 {
|
||||||
|
blockinfo = respReferesh.ResultData.UserBlockInfo[0]
|
||||||
|
return nil, "BLOCKED", blockinfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, respReferesh.ResultCode, blockinfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mg *Maingate) platform_hybeim_getuserinfo(info usertokeninfo) (bool, string, string) {
|
||||||
|
// Hybeim ( Steam )도 이메일 정보를 받을수 없기 때문에 userid로 리턴한다.
|
||||||
|
dummyEmail := fmt.Sprintf("%s@hibeim.id", info.userid)
|
||||||
|
return true, info.userid, dummyEmail
|
||||||
|
|
||||||
|
}
|
||||||
@ -83,9 +83,9 @@ func (mg *Maingate) platform_microsoft_get_login_url(w http.ResponseWriter, r *h
|
|||||||
}
|
}
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.MicrosoftClientId)
|
params.Add("client_id", config.MicrosoftClientId)
|
||||||
params.Add("response_type", "code")
|
params.Add("response_type", "code")
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||||
params.Add("response_mode", "query")
|
params.Add("response_mode", "query")
|
||||||
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ func (mg *Maingate) platform_microsoft_authorize(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
|
||||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformMicrosoft, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r *http.Request) {
|
func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -191,13 +191,13 @@ func (mg *Maingate) platform_microsoft_authorize_result(w http.ResponseWriter, r
|
|||||||
//=================
|
//=================
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.MicrosoftClientId)
|
params.Add("client_id", config.MicrosoftClientId)
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||||
params.Add("code", code)
|
params.Add("code", code)
|
||||||
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
||||||
params.Add("grant_type", "authorization_code")
|
params.Add("grant_type", "authorization_code")
|
||||||
|
|
||||||
params.Add("client_secret", mg.MicrosoftClientSecret)
|
params.Add("client_secret", config.MicrosoftClientSecret)
|
||||||
|
|
||||||
var respReferesh Microsoft_ValidationResponse
|
var respReferesh Microsoft_ValidationResponse
|
||||||
acceestoken_expire_time := time.Now().Unix()
|
acceestoken_expire_time := time.Now().Unix()
|
||||||
@ -263,13 +263,13 @@ func (mg *Maingate) platform_microsoft_getuserinfo(info usertokeninfo) (bool, st
|
|||||||
if time.Now().Unix() > info.accesstoken_expire_time {
|
if time.Now().Unix() > info.accesstoken_expire_time {
|
||||||
|
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("client_id", mg.MicrosoftClientId)
|
params.Add("client_id", config.MicrosoftClientId)
|
||||||
params.Add("redirect_uri", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
params.Add("redirect_uri", config.RedirectBaseUrl+"/authorize/"+AuthPlatformMicrosoft)
|
||||||
params.Add("refresh_token", info.token)
|
params.Add("refresh_token", info.token)
|
||||||
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
params.Add("scope", "openid offline_access https://graph.microsoft.com/mail.read")
|
||||||
params.Add("grant_type", "refresh_token")
|
params.Add("grant_type", "refresh_token")
|
||||||
|
|
||||||
params.Add("client_secret", mg.MicrosoftClientSecret)
|
params.Add("client_secret", config.MicrosoftClientSecret)
|
||||||
|
|
||||||
var respReferesh Microsoft_ValidationResponse
|
var respReferesh Microsoft_ValidationResponse
|
||||||
acceestoken_expire_time := time.Now().Unix()
|
acceestoken_expire_time := time.Now().Unix()
|
||||||
|
|||||||
121
core/platformsteam.go
Normal file
121
core/platformsteam.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SteamSDKAuthInfo struct {
|
||||||
|
UserSteamId string `json:"steamid"`
|
||||||
|
UserAuthToken string `json:"authtoken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mg *Maingate) platform_steamsdk_authorize(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
brinfo, err := mg.GetUserBrowserInfo(r)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
logger.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var authinfo SteamSDKAuthInfo
|
||||||
|
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&authinfo)
|
||||||
|
if err != nil {
|
||||||
|
logger.Println("authinfo decoding fail:", err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := authenticateSteamUser(config.SteamPublisherAuthKey, config.SteamAppId, authinfo.UserSteamId, authinfo.UserAuthToken); err == nil {
|
||||||
|
acceestoken_expire_time := time.Date(2999, 1, int(time.January), 0, 0, 0, 0, time.UTC).Unix()
|
||||||
|
|
||||||
|
var info usertokeninfo
|
||||||
|
info.platform = AuthPlatformSteamSDK
|
||||||
|
info.userid = authinfo.UserSteamId
|
||||||
|
info.token = authinfo.UserAuthToken
|
||||||
|
info.brinfo = brinfo
|
||||||
|
//info.accesstoken = respReferesh.AccessToken
|
||||||
|
info.accesstoken_expire_time = acceestoken_expire_time
|
||||||
|
mg.setUserToken(info)
|
||||||
|
|
||||||
|
params := url.Values{}
|
||||||
|
params.Add("id", authinfo.UserSteamId)
|
||||||
|
params.Add("authtype", AuthPlatformSteamSDK)
|
||||||
|
w.Write([]byte("?" + params.Encode()))
|
||||||
|
//http.Redirect(w, r, "actionsquare://login?"+Result, http.StatusSeeOther)
|
||||||
|
} else {
|
||||||
|
logger.Println(err)
|
||||||
|
http.Redirect(w, r, "actionsquare://error", http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func authenticateSteamUser(pubkey, appid, playerid, ticket string) error {
|
||||||
|
// Returns: The user's 64-bit SteamID if the user's ticket is valid
|
||||||
|
url := fmt.Sprintf("https://partner.steam-api.com/ISteamUserAuth/AuthenticateUserTicket/v1/?key=%s&appid=%s&ticket=%s", pubkey, appid, ticket)
|
||||||
|
resp, e := http.Get(url)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
io.Copy(io.Discard, resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
body, e := ioutil.ReadAll(resp.Body)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Println(url)
|
||||||
|
// fmt.Println(string(body))
|
||||||
|
|
||||||
|
var doc map[string]interface{}
|
||||||
|
if err := json.Unmarshal(body, &doc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := doc["response"]; ok {
|
||||||
|
response := v.(map[string]interface{})
|
||||||
|
if v, ok = response["params"]; ok {
|
||||||
|
paramsnode := v.(map[string]interface{})
|
||||||
|
if v, ok = paramsnode["result"]; ok {
|
||||||
|
if v.(string) == "OK" {
|
||||||
|
if v, ok = paramsnode["steamid"]; ok {
|
||||||
|
// playerid에는 빌드 구성 suffix가 붙어있는 상태이므로 == 비교가 아니라 HasPrefix로 비교
|
||||||
|
if strings.HasPrefix(playerid, v.(string)) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if v.(string) == "Invalid ticket" {
|
||||||
|
return errors.New("steam: invalid ticket")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if errdocraw, ok := response["error"]; ok {
|
||||||
|
errdoc := errdocraw.(map[string]interface{})
|
||||||
|
desc := errdoc["errordesc"].(string)
|
||||||
|
return errors.New(desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.New("steam: response is not expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mg *Maingate) platform_steamsdk_getuserinfo(info usertokeninfo) (bool, string, string) {
|
||||||
|
// Steam은 이메일 정보를 받을수 없기 때문에 userid로 리턴한다.
|
||||||
|
dummyEmail := fmt.Sprintf("%s@steam.id", info.userid)
|
||||||
|
return true, info.userid, dummyEmail
|
||||||
|
|
||||||
|
}
|
||||||
@ -123,7 +123,7 @@ func (mg *Maingate) platform_twitter_authorize(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
|
||||||
http.Redirect(w, r, mg.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
http.Redirect(w, r, config.RedirectBaseUrl+"/authorize_result/"+AuthPlatformTwitter, http.StatusSeeOther) //-- 바로 받으니까 쿠키 안와서 한번 더 Redirect 시킨다.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) platform_twitter_authorize_result(w http.ResponseWriter, r *http.Request) {
|
func (mg *Maingate) platform_twitter_authorize_result(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -222,14 +222,13 @@ func (mg *Maingate) platform_twitter_authorize_result(w http.ResponseWriter, r *
|
|||||||
|
|
||||||
func (mg *Maingate) platform_twitter_getuserinfo(token, secret string) (bool, string, string) {
|
func (mg *Maingate) platform_twitter_getuserinfo(token, secret string) (bool, string, string) {
|
||||||
|
|
||||||
result := mg.CallTwitterAPI("https://api.twitter.com/2/users/me", "GET", token, secret, mg.GeneratePlatformLoginNonceKey())
|
result := mg.CallTwitterAPI("https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true", "GET", token, secret, mg.GeneratePlatformLoginNonceKey())
|
||||||
|
|
||||||
var TwitterUserInfo struct {
|
var TwitterUserInfo struct {
|
||||||
Data struct {
|
Id string `json:"id_str"`
|
||||||
Id string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Username string `json:"username"`
|
Username string `json:"screen_name"`
|
||||||
} `json:"data"`
|
Email string `json:"email"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(result), &TwitterUserInfo)
|
err := json.Unmarshal([]byte(result), &TwitterUserInfo)
|
||||||
@ -240,16 +239,17 @@ func (mg *Maingate) platform_twitter_getuserinfo(token, secret string) (bool, st
|
|||||||
|
|
||||||
// fmt.Println("=====================")
|
// fmt.Println("=====================")
|
||||||
// fmt.Println(result)
|
// fmt.Println(result)
|
||||||
// fmt.Println(TwitterUserInfo.Data.Id)
|
// fmt.Println(TwitterUserInfo.Id)
|
||||||
// fmt.Println(TwitterUserInfo.Data.Name)
|
// fmt.Println(TwitterUserInfo.Name)
|
||||||
// fmt.Println(TwitterUserInfo.Data.Username)
|
// fmt.Println(TwitterUserInfo.Username)
|
||||||
|
// fmt.Println(TwitterUserInfo.Email)
|
||||||
// fmt.Println("=====================")
|
// fmt.Println("=====================")
|
||||||
|
|
||||||
return true, TwitterUserInfo.Data.Id, ""
|
return true, TwitterUserInfo.Id, TwitterUserInfo.Email
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) CallTwitterAPI_WithAPPKey(requesturl, method, nonce string) string {
|
func (mg *Maingate) CallTwitterAPI_WithAPPKey(requesturl, method, nonce string) string {
|
||||||
return mg.CallTwitterAPI(requesturl, method, mg.TwitterOAuthKey, mg.TwitterOAuthSecret, nonce)
|
return mg.CallTwitterAPI(requesturl, method, config.TwitterOAuthKey, config.TwitterOAuthSecret, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret, nonce string) string {
|
func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret, nonce string) string {
|
||||||
@ -272,8 +272,8 @@ func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret
|
|||||||
//vals.Add("oauth_callback", "actionclient://callback")
|
//vals.Add("oauth_callback", "actionclient://callback")
|
||||||
//vals.Add("oauth_callback", "http://127.0.0.1:7770/auth")
|
//vals.Add("oauth_callback", "http://127.0.0.1:7770/auth")
|
||||||
|
|
||||||
vals.Add("oauth_callback", mg.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
|
vals.Add("oauth_callback", config.RedirectBaseUrl+"/authorize/"+AuthPlatformTwitter)
|
||||||
vals.Add("oauth_consumer_key", mg.TwitterCustomerKey)
|
vals.Add("oauth_consumer_key", config.TwitterCustomerKey)
|
||||||
vals.Add("oauth_token", oauth_token)
|
vals.Add("oauth_token", oauth_token)
|
||||||
vals.Add("oauth_signature_method", "HMAC-SHA1")
|
vals.Add("oauth_signature_method", "HMAC-SHA1")
|
||||||
vals.Add("oauth_timestamp", strconv.Itoa(int(time.Now().Unix())))
|
vals.Add("oauth_timestamp", strconv.Itoa(int(time.Now().Unix())))
|
||||||
@ -282,7 +282,7 @@ func (mg *Maingate) CallTwitterAPI(requesturl, method, oauth_token, oauth_secret
|
|||||||
|
|
||||||
parameterString := strings.Replace(vals.Encode(), "+", "%20", -1)
|
parameterString := strings.Replace(vals.Encode(), "+", "%20", -1)
|
||||||
signatureBase := strings.ToUpper(method) + "&" + url.QueryEscape(strings.Split(requesturl, "?")[0]) + "&" + url.QueryEscape(parameterString)
|
signatureBase := strings.ToUpper(method) + "&" + url.QueryEscape(strings.Split(requesturl, "?")[0]) + "&" + url.QueryEscape(parameterString)
|
||||||
signingKey := url.QueryEscape(mg.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret)
|
signingKey := url.QueryEscape(config.TwitterCustomerSecret) + "&" + url.QueryEscape(oauth_secret)
|
||||||
signature := calculateTwitterSignature(signatureBase, signingKey)
|
signature := calculateTwitterSignature(signatureBase, signingKey)
|
||||||
|
|
||||||
headerString := "OAuth oauth_callback=\"" + url.QueryEscape(vals.Get("oauth_callback")) + "\", oauth_consumer_key=\"" + url.QueryEscape(vals.Get("oauth_consumer_key")) + "\", oauth_nonce=\"" + url.QueryEscape(vals.Get("oauth_nonce")) +
|
headerString := "OAuth oauth_callback=\"" + url.QueryEscape(vals.Get("oauth_callback")) + "\", oauth_consumer_key=\"" + url.QueryEscape(vals.Get("oauth_consumer_key")) + "\", oauth_nonce=\"" + url.QueryEscape(vals.Get("oauth_nonce")) +
|
||||||
|
|||||||
1080
core/service.go
1080
core/service.go
File diff suppressed because it is too large
Load Diff
271
core/watch.go
271
core/watch.go
@ -1,17 +1,15 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
common "repositories.action2quare.com/ayo/gocommon"
|
"repositories.action2quare.com/ayo/gocommon"
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
@ -20,14 +18,6 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
type authPipelineDocument struct {
|
|
||||||
OperationType string `bson:"operationType"`
|
|
||||||
DocumentKey struct {
|
|
||||||
Id primitive.ObjectID `bson:"_id"`
|
|
||||||
} `bson:"documentKey"`
|
|
||||||
Authinfo *common.Authinfo `bson:"fullDocument"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type servicePipelineDocument struct {
|
type servicePipelineDocument struct {
|
||||||
OperationType string `bson:"operationType"`
|
OperationType string `bson:"operationType"`
|
||||||
DocumentKey struct {
|
DocumentKey struct {
|
||||||
@ -41,102 +31,10 @@ type filePipelineDocument struct {
|
|||||||
DocumentKey struct {
|
DocumentKey struct {
|
||||||
Id primitive.ObjectID `bson:"_id"`
|
Id primitive.ObjectID `bson:"_id"`
|
||||||
} `bson:"documentKey"`
|
} `bson:"documentKey"`
|
||||||
File *fileDocumentDesc `bson:"fullDocument"`
|
File *FileDocumentDesc `bson:"fullDocument"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type whilelistPipelineDocument struct {
|
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
|
||||||
OperationType string `bson:"operationType"`
|
|
||||||
DocumentKey struct {
|
|
||||||
Id primitive.ObjectID `bson:"_id"`
|
|
||||||
} `bson:"documentKey"`
|
|
||||||
Member *whitelistmember `bson:"fullDocument"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) watchWhitelistCollection(parentctx context.Context) {
|
|
||||||
defer func() {
|
|
||||||
s := recover()
|
|
||||||
if s != nil {
|
|
||||||
logger.Error(s)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
matchStage := bson.D{
|
|
||||||
{
|
|
||||||
Key: "$match", Value: bson.D{
|
|
||||||
{Key: "operationType", Value: bson.D{
|
|
||||||
{Key: "$in", Value: bson.A{
|
|
||||||
"update",
|
|
||||||
"insert",
|
|
||||||
}},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
projectStage := bson.D{
|
|
||||||
{
|
|
||||||
Key: "$project", Value: bson.D{
|
|
||||||
{Key: "documentKey", Value: 1},
|
|
||||||
{Key: "operationType", Value: 1},
|
|
||||||
{Key: "fullDocument", Value: 1},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var stream *mongo.ChangeStream
|
|
||||||
var err error
|
|
||||||
var ctx context.Context
|
|
||||||
|
|
||||||
for {
|
|
||||||
if stream == nil {
|
|
||||||
stream, err = mg.mongoClient.Watch(CollectionWhitelist, mongo.Pipeline{matchStage, projectStage})
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("watchWhitelistCollection watch failed :", err)
|
|
||||||
time.Sleep(time.Minute)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ctx = context.TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
changed := stream.TryNext(ctx)
|
|
||||||
if ctx.Err() != nil {
|
|
||||||
logger.Error("watchServiceCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if changed {
|
|
||||||
var data whilelistPipelineDocument
|
|
||||||
if err := stream.Decode(&data); err == nil {
|
|
||||||
ot := data.OperationType
|
|
||||||
switch ot {
|
|
||||||
case "insert":
|
|
||||||
// 새 화이트리스트 멤버
|
|
||||||
if svc := mg.services.get(data.Member.Service); svc != nil {
|
|
||||||
svc.wl.add(data.Member)
|
|
||||||
}
|
|
||||||
case "update":
|
|
||||||
if svc := mg.services.get(data.Member.Service); svc != nil {
|
|
||||||
if data.Member.Expired != 0 {
|
|
||||||
logger.Println("whitelist member is removed :", *data.Member)
|
|
||||||
svc.wl.remove(data.Member.Email)
|
|
||||||
} else {
|
|
||||||
logger.Println("whitelist member is updated :", *data.Member)
|
|
||||||
svc.wl.add(data.Member)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.Error("watchServiceCollection stream.Decode failed :", err)
|
|
||||||
}
|
|
||||||
} else if stream.Err() != nil || stream.ID() == 0 {
|
|
||||||
logger.Error("watchServiceCollection stream error :", stream.Err())
|
|
||||||
stream.Close(ctx)
|
|
||||||
stream = nil
|
|
||||||
} else {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
|
|
||||||
defer func() {
|
defer func() {
|
||||||
s := recover()
|
s := recover()
|
||||||
if s != nil {
|
if s != nil {
|
||||||
@ -187,9 +85,17 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *htt
|
|||||||
|
|
||||||
if !changed {
|
if !changed {
|
||||||
if stream.Err() != nil || stream.ID() == 0 {
|
if stream.Err() != nil || stream.ID() == 0 {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
logger.Println("watchServiceCollection is done")
|
||||||
|
stream.Close(ctx)
|
||||||
|
return
|
||||||
|
|
||||||
|
case <-time.After(time.Second):
|
||||||
logger.Error("watchServiceCollection stream error :", stream.Err())
|
logger.Error("watchServiceCollection stream error :", stream.Err())
|
||||||
stream.Close(ctx)
|
stream.Close(ctx)
|
||||||
stream = nil
|
stream = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
@ -200,7 +106,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *htt
|
|||||||
if err := stream.Decode(&data); err == nil {
|
if err := stream.Decode(&data); err == nil {
|
||||||
switch data.OperationType {
|
switch data.OperationType {
|
||||||
case "insert":
|
case "insert":
|
||||||
data.File.save()
|
data.File.Save()
|
||||||
|
|
||||||
case "delete":
|
case "delete":
|
||||||
subfolder := hex.EncodeToString(data.DocumentKey.Id[:4])
|
subfolder := hex.EncodeToString(data.DocumentKey.Id[:4])
|
||||||
@ -213,7 +119,7 @@ func (mg *Maingate) watchFileCollection(parentctx context.Context, serveMux *htt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *http.ServeMux, prefix string) {
|
func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux gocommon.ServerMuxInterface, prefix string) {
|
||||||
defer func() {
|
defer func() {
|
||||||
s := recover()
|
s := recover()
|
||||||
if s != nil {
|
if s != nil {
|
||||||
@ -226,7 +132,6 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *
|
|||||||
Key: "$match", Value: bson.D{
|
Key: "$match", Value: bson.D{
|
||||||
{Key: "operationType", Value: bson.D{
|
{Key: "operationType", Value: bson.D{
|
||||||
{Key: "$in", Value: bson.A{
|
{Key: "$in", Value: bson.A{
|
||||||
"delete",
|
|
||||||
"insert",
|
"insert",
|
||||||
"update",
|
"update",
|
||||||
"replace",
|
"replace",
|
||||||
@ -274,9 +179,11 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *
|
|||||||
if err := data.Service.prepare(mg); err != nil {
|
if err := data.Service.prepare(mg); err != nil {
|
||||||
logger.Error("service cannot be prepared :", data.Service, err)
|
logger.Error("service cannot be prepared :", data.Service, err)
|
||||||
} else {
|
} else {
|
||||||
|
// 내가 임시로 가지고 있던 서비스일 수 있다.
|
||||||
|
if mg.service().Id == data.Service.Id {
|
||||||
logger.Println("service is on the board! :", data.Service)
|
logger.Println("service is on the board! :", data.Service)
|
||||||
mg.services.add(data.Service)
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
|
||||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, data.Service.ServiceCode, "/"), data.Service)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case "replace":
|
case "replace":
|
||||||
@ -284,147 +191,23 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *
|
|||||||
|
|
||||||
case "update":
|
case "update":
|
||||||
data.Service.prepare(mg)
|
data.Service.prepare(mg)
|
||||||
if old := mg.services.get(data.Service.ServiceName); old != nil {
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
|
||||||
atomic.SwapPointer(&old.divisionsForUsersSerialized, data.Service.divisionsForUsersSerialized)
|
|
||||||
atomic.SwapPointer(&old.divisionsSerialized, data.Service.divisionsSerialized)
|
|
||||||
atomic.SwapPointer(&old.apiUsers, data.Service.apiUsers)
|
|
||||||
atomic.SwapPointer(&old.serviceSerialized, data.Service.serviceSerialized)
|
|
||||||
atomic.SwapPointer(&old.serviceSummarySerialized, data.Service.serviceSummarySerialized)
|
|
||||||
|
|
||||||
for _, token := range old.ServerApiTokens {
|
|
||||||
mg.apiTokenToService.remove(token.Hex())
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, token := range data.Service.ServerApiTokens {
|
|
||||||
mg.apiTokenToService.add(token.Hex(), data.Service.ServiceCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.Service.UseWhitelist {
|
|
||||||
atomic.StoreInt32(&old.wl.working, 1)
|
|
||||||
} else {
|
|
||||||
atomic.StoreInt32(&old.wl.working, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
old.Closed = data.Service.Closed
|
|
||||||
if old.Closed {
|
|
||||||
atomic.StoreInt32(&old.closed, 1)
|
|
||||||
} else {
|
|
||||||
atomic.StoreInt32(&old.closed, 0)
|
|
||||||
}
|
|
||||||
atomic.SwapPointer(&old.wl.emailptr, data.Service.wl.emailptr)
|
|
||||||
|
|
||||||
old.Divisions = data.Service.Divisions
|
|
||||||
for _, div := range old.Divisions {
|
|
||||||
var req *http.Request
|
|
||||||
if div.State == DivisionState_FullOpen {
|
|
||||||
req, _ = http.NewRequest("POST", div.Url+"/maingate", nil)
|
|
||||||
} else if div.Maintenance != nil {
|
|
||||||
bt, _ := json.Marshal(div.Maintenance)
|
|
||||||
req, _ = http.NewRequest("POST", div.Url+"/maingate", bytes.NewBuffer(bt))
|
|
||||||
}
|
|
||||||
|
|
||||||
if req != nil {
|
|
||||||
// MG-X-API-TOKEN
|
|
||||||
req.Header.Add("MG-X-API-TOKEN", old.ServerApiTokens[0].Hex())
|
|
||||||
if resp, err := http.DefaultClient.Do(req); err == nil {
|
|
||||||
resp.Body.Close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if !data.Service.Closed {
|
|
||||||
logger.Println("service is on the board! :", data.Service)
|
|
||||||
mg.services.add(data.Service)
|
|
||||||
serveMux.Handle(common.MakeHttpHandlerPattern(prefix, data.Service.ServiceCode, "/"), data.Service)
|
|
||||||
}
|
|
||||||
case "delete":
|
|
||||||
if deleted := mg.services.remove(data.DocumentKey.Id); deleted != nil {
|
|
||||||
logger.Println("service is closed :", data.Service)
|
|
||||||
atomic.AddInt32(&deleted.closed, 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.Error("watchServiceCollection stream.Decode failed :", err)
|
logger.Error("watchServiceCollection stream.Decode failed :", err)
|
||||||
}
|
}
|
||||||
} else if stream.Err() != nil || stream.ID() == 0 {
|
} else if stream.Err() != nil || stream.ID() == 0 {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
logger.Println("watchServiceCollection is done")
|
||||||
|
stream.Close(ctx)
|
||||||
|
return
|
||||||
|
|
||||||
|
case <-time.After(time.Second):
|
||||||
logger.Error("watchServiceCollection stream error :", stream.Err())
|
logger.Error("watchServiceCollection stream error :", stream.Err())
|
||||||
stream.Close(ctx)
|
stream.Close(ctx)
|
||||||
stream = nil
|
stream = nil
|
||||||
} else {
|
}
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func watchAuthCollection(parentctx context.Context, ac *common.AuthCollection, mongoClient common.MongoClient) {
|
|
||||||
defer func() {
|
|
||||||
s := recover()
|
|
||||||
if s != nil {
|
|
||||||
logger.Error(s)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
matchStage := bson.D{
|
|
||||||
{
|
|
||||||
Key: "$match", Value: bson.D{
|
|
||||||
{Key: "operationType", Value: bson.D{
|
|
||||||
{Key: "$in", Value: bson.A{
|
|
||||||
"delete",
|
|
||||||
"insert",
|
|
||||||
"update",
|
|
||||||
}},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
projectStage := bson.D{
|
|
||||||
{
|
|
||||||
Key: "$project", Value: bson.D{
|
|
||||||
{Key: "documentKey", Value: 1},
|
|
||||||
{Key: "operationType", Value: 1},
|
|
||||||
{Key: "fullDocument", Value: 1},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var stream *mongo.ChangeStream
|
|
||||||
var err error
|
|
||||||
var ctx context.Context
|
|
||||||
|
|
||||||
for {
|
|
||||||
if stream == nil {
|
|
||||||
stream, err = mongoClient.Watch(CollectionAuth, mongo.Pipeline{matchStage, projectStage})
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("watchAuthCollection watch failed :", err)
|
|
||||||
time.Sleep(time.Minute)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ctx = context.TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
changed := stream.TryNext(ctx)
|
|
||||||
if ctx.Err() != nil {
|
|
||||||
logger.Error("watchAuthCollection stream.TryNext failed. process should be restarted! :", ctx.Err().Error())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if changed {
|
|
||||||
var data authPipelineDocument
|
|
||||||
if err := stream.Decode(&data); err == nil {
|
|
||||||
ot := data.OperationType
|
|
||||||
switch ot {
|
|
||||||
case "insert":
|
|
||||||
ac.AddRaw(&mongoAuthCell{src: data.Authinfo})
|
|
||||||
case "update":
|
|
||||||
ac.AddRaw(&mongoAuthCell{src: data.Authinfo})
|
|
||||||
case "delete":
|
|
||||||
ac.RemoveByAccId(data.DocumentKey.Id)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.Error("watchAuthCollection stream.Decode failed :", err)
|
|
||||||
}
|
|
||||||
} else if stream.Err() != nil || stream.ID() == 0 {
|
|
||||||
logger.Error("watchAuthCollection stream error :", stream.Err())
|
|
||||||
stream.Close(ctx)
|
|
||||||
stream = nil
|
|
||||||
} else {
|
} else {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
|||||||
11
fba/track-event.html
Normal file
11
fba/track-event.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" src="./fb-ga.min.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- <body> -->
|
||||||
|
<!-- <body onload="window.FBA.TrackLogEvent('DESKTOP-TEST');"> -->
|
||||||
|
<!-- <script type="cjs" src="./fb-ga.rollup.js"> -->
|
||||||
76
go.mod
76
go.mod
@ -1,55 +1,63 @@
|
|||||||
module repositories.action2quare.com/ayo/maingate
|
module repositories.action2quare.com/ayo/maingate
|
||||||
|
|
||||||
go 1.19
|
go 1.22.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
firebase.google.com/go v3.13.0+incompatible
|
firebase.google.com/go v3.13.0+incompatible
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||||
go.mongodb.org/mongo-driver v1.11.6
|
go.mongodb.org/mongo-driver v1.11.7
|
||||||
google.golang.org/api v0.123.0
|
google.golang.org/api v0.157.0
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230528100715-93bd4f6c0bab
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.110.2 // indirect
|
cloud.google.com/go v0.111.0 // indirect
|
||||||
cloud.google.com/go/compute v1.19.0 // indirect
|
cloud.google.com/go/compute v1.23.3 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
cloud.google.com/go/firestore v1.10.0 // indirect
|
cloud.google.com/go/firestore v1.14.0 // indirect
|
||||||
cloud.google.com/go/iam v0.13.0 // indirect
|
cloud.google.com/go/iam v1.1.5 // indirect
|
||||||
cloud.google.com/go/longrunning v0.4.2 // indirect
|
cloud.google.com/go/longrunning v0.5.4 // indirect
|
||||||
cloud.google.com/go/storage v1.29.0 // indirect
|
cloud.google.com/go/storage v1.30.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
|
github.com/go-logr/logr v1.3.0 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/s2a-go v0.1.7 // indirect
|
||||||
github.com/google/s2a-go v0.1.4 // indirect
|
github.com/google/uuid v1.5.0 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
|
github.com/klauspost/compress v1.16.6 // indirect
|
||||||
github.com/klauspost/compress v1.13.6 // indirect
|
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
|
||||||
github.com/pires/go-proxyproto v0.7.0 // indirect
|
github.com/pires/go-proxyproto v0.7.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||||
github.com/xdg-go/scram v1.1.1 // indirect
|
github.com/xdg-go/scram v1.1.2 // indirect
|
||||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
golang.org/x/crypto v0.9.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
|
||||||
golang.org/x/net v0.10.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
|
||||||
golang.org/x/oauth2 v0.8.0 // indirect
|
go.opentelemetry.io/otel v1.21.0 // indirect
|
||||||
golang.org/x/sync v0.2.0 // indirect
|
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||||
golang.org/x/sys v0.8.0 // indirect
|
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||||
golang.org/x/text v0.9.0 // indirect
|
golang.org/x/crypto v0.18.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/net v0.20.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/oauth2 v0.16.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
golang.org/x/sys v0.16.0 // indirect
|
||||||
google.golang.org/grpc v1.55.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||||
|
google.golang.org/grpc v1.60.1 // indirect
|
||||||
|
google.golang.org/protobuf v1.32.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace repositories.action2quare.com/ayo/maingate => ./
|
|
||||||
|
|||||||
180
go.sum
180
go.sum
@ -1,34 +1,27 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM=
|
||||||
cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
|
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
|
||||||
cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
|
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
||||||
cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ=
|
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
||||||
cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
|
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||||
cloud.google.com/go/firestore v1.10.0 h1:FG5C49ukKKqyljY+XNRZGae1HZaiVe7aoqi2BipnBuM=
|
cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw=
|
||||||
cloud.google.com/go/firestore v1.10.0/go.mod h1:eAeoQCV8F35Mcy4k8ZrQbcSYZOayIwoiU7ZJ6xzH1+o=
|
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
|
||||||
cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
|
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||||
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
|
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||||
cloud.google.com/go/longrunning v0.4.2 h1:WDKiiNXFTaQ6qz/G8FCOkuY9kJmOJGY67wPUC1M2RbE=
|
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg=
|
||||||
cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ=
|
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
|
||||||
cloud.google.com/go/storage v1.29.0 h1:6weCgzRvMg7lzuUurI4697AqIRPU1SvzHhynwpW31jI=
|
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||||
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
|
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
|
||||||
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
|
||||||
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
|
||||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
|
||||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -37,11 +30,16 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
|
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
|
||||||
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||||
|
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
@ -52,16 +50,13 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
|
|||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
@ -78,28 +73,28 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||||
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
|
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||||
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||||
github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
|
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||||
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
|
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
|
||||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
|
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
|
||||||
|
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||||
|
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||||
|
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||||
@ -110,40 +105,50 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
|
||||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
|
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||||
|
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||||
|
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
|
||||||
|
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.mongodb.org/mongo-driver v1.11.6 h1:XM7G6PjiGAO5betLF13BIa5TlLUUE3uJ/2Ox3Lz1K+o=
|
go.mongodb.org/mongo-driver v1.11.7 h1:LIwYxASDLGUg/8wOhgOOZhX8tQa/9tgZPgzZoVqJvcs=
|
||||||
go.mongodb.org/mongo-driver v1.11.6/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
|
go.mongodb.org/mongo-driver v1.11.7/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
||||||
|
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||||
|
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||||
|
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
||||||
|
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
|
||||||
|
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||||
|
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
@ -151,55 +156,48 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||||
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
|
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||||
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
@ -209,31 +207,29 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
google.golang.org/api v0.157.0 h1:ORAeqmbrrozeyw5NjnMxh7peHO0UzV4wWYSwZeCUb20=
|
||||||
google.golang.org/api v0.123.0 h1:yHVU//vA+qkOhm4reEC9LtzHVUCN/IqqNRl1iQ9xE20=
|
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g=
|
||||||
google.golang.org/api v0.123.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=
|
||||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
|
||||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
|
||||||
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
|
|
||||||
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@ -245,22 +241,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
|||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230524061015-e95efa06a6d4 h1:DFrkLvbPWqwVDU4X0QGJs2lhPduJYJU+JM/r1L2RMwo=
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86 h1:vP0mVST68cw14fI/af3Xp1ZQoYjkNGK4S0zji1BVfSI=
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230524061015-e95efa06a6d4/go.mod h1:pw573a06qV7dP1lSyavbWmzyYAsmwtK6mdbFENbh3cs=
|
repositories.action2quare.com/ayo/gocommon v0.0.0-20240806115838-ca5632031c86/go.mod h1:XA8+hQtUNh956T+kAbJKkUtMl5HUWj83knvdBvvPS5s=
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230524093812-0acae49a22e7 h1:4U70jZtyMQpcF1T8z/HU8LOR2/MXoF2eJvun6lbnyuo=
|
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230524093812-0acae49a22e7/go.mod h1:5RmALPCFGFmqXa+AAPLsQaSlBVBafwX1H2CnIhsCM50=
|
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230528100715-93bd4f6c0bab h1:EMlxwDayv3rn8ttJcJuDLYoHA5odVn85+LjdAuw+2dw=
|
|
||||||
repositories.action2quare.com/ayo/gocommon v0.0.0-20230528100715-93bd4f6c0bab/go.mod h1:ng62uGMGXyQSeuxePG5gJAMtip4Rnspu5Tu7hgvaXns=
|
|
||||||
|
|||||||
31
main.go
31
main.go
@ -2,47 +2,46 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"flag"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
|
||||||
|
|
||||||
common "repositories.action2quare.com/ayo/gocommon"
|
|
||||||
"repositories.action2quare.com/ayo/maingate/core"
|
|
||||||
|
|
||||||
|
"repositories.action2quare.com/ayo/gocommon"
|
||||||
|
"repositories.action2quare.com/ayo/gocommon/flagx"
|
||||||
"repositories.action2quare.com/ayo/gocommon/logger"
|
"repositories.action2quare.com/ayo/gocommon/logger"
|
||||||
|
"repositories.action2quare.com/ayo/maingate/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// linux : go build --ldflags="-X 'main.revision=$(git rev-parse --short HEAD)'"
|
// linux : go build --ldflags="-X 'main.revision=$(git rev-parse --short HEAD)'"
|
||||||
// windows : for /f usebackq %F in (`git rev-parse --short HEAD`) do go build --ldflags="-X 'main.revision=%F'"
|
// windows : for /f usebackq %F in (`git rev-parse --short HEAD`) do go build --ldflags="-X 'main.revision=%F'"
|
||||||
var revision = "0000000"
|
var revision = "0000000"
|
||||||
|
var prefix = flagx.String("prefix", "", "")
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if !flag.Parsed() {
|
flagx.Parse()
|
||||||
flag.Parse()
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Println("build revision =", revision)
|
logger.Println("build revision =", revision)
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
mg, err := core.New(ctx)
|
mg, err := core.New(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("core.New failed :", err)
|
logger.Error("core.New failed :", err)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
defer mg.Destructor()
|
||||||
|
|
||||||
serveMux := http.NewServeMux()
|
serveMux := http.NewServeMux()
|
||||||
if err := mg.RegisterHandlers(ctx, serveMux, *common.PrefixPtr); err != nil {
|
if err := mg.RegisterHandlers(ctx, serveMux, *prefix); err != nil {
|
||||||
logger.Error("RegisterHandlers failed :", err)
|
logger.Error("RegisterHandlers failed :", err)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
server := common.NewHTTPServer(serveMux)
|
server := gocommon.NewHTTPServer(serveMux)
|
||||||
logger.Println("maingate is started")
|
logger.Println("maingate is started")
|
||||||
|
|
||||||
if err := server.Start(); err != nil {
|
if err := server.Start(); err != nil {
|
||||||
logger.Error("maingate is stopped with error :", err)
|
logger.Error("maingate is stopped with error :", err)
|
||||||
}
|
}
|
||||||
cancel()
|
|
||||||
mg.Destructor()
|
logger.Println("maingate is terminated")
|
||||||
}
|
}
|
||||||
|
|||||||
1
template/fb-ga.min.js
vendored
Normal file
1
template/fb-ga.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
223
www/gamepot.html
223
www/gamepot.html
@ -1,223 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>GamePot JS SDK Sandbox</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<!-- <meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
|
||||||
/> -->
|
|
||||||
|
|
||||||
<!-- <link
|
|
||||||
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
|
||||||
rel="stylesheet"
|
|
||||||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
/> -->
|
|
||||||
<!-- <script src="https://gamepot.gcdn.ntruss.com/gamepot-sdk-javascript-lastest.min.js"></script> -->
|
|
||||||
<script src="https://cdn.gamepot.io/dev/gamepot-sdk-javascript-1.0.19-b1.min.js"></script>
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="container-fluid" style="margin-bottom: 200px;">
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
function onLoginsuccess(user) {
|
|
||||||
// -- 로그인 성공
|
|
||||||
// id: 회원 아이디
|
|
||||||
// token: 로그인 토큰(JWT)
|
|
||||||
// nickname: 닉네임
|
|
||||||
// provider: 소셜 로그인 종류
|
|
||||||
// providerId: 소셜 로그인 ID
|
|
||||||
// verify: 인증여부
|
|
||||||
// agree: 약관 동의 여부
|
|
||||||
//===========================
|
|
||||||
|
|
||||||
const formauth = document.createElement('form');
|
|
||||||
let objs1 = document.createElement('input');
|
|
||||||
objs1.setAttribute('type', 'hidden');
|
|
||||||
objs1.setAttribute('name', 'state');
|
|
||||||
objs1.setAttribute('value', '{{ .State }}');
|
|
||||||
formauth.appendChild(objs1);
|
|
||||||
|
|
||||||
let objs2 = document.createElement('input');
|
|
||||||
objs2.setAttribute('type', 'hidden');
|
|
||||||
objs2.setAttribute('name', 'id');
|
|
||||||
objs2.setAttribute('value', `${user.id}`);
|
|
||||||
formauth.appendChild(objs2);
|
|
||||||
|
|
||||||
let objs3 = document.createElement('input');
|
|
||||||
objs3.setAttribute('type', 'hidden');
|
|
||||||
objs3.setAttribute('name', 'code');
|
|
||||||
objs3.setAttribute('value', `${user.token}`);
|
|
||||||
formauth.appendChild(objs3);
|
|
||||||
|
|
||||||
let objs4 = document.createElement('input');
|
|
||||||
objs4.setAttribute('type', 'hidden');
|
|
||||||
objs4.setAttribute('name', 'nickname');
|
|
||||||
objs4.setAttribute('value', `${user.nickname}`);
|
|
||||||
formauth.appendChild(objs4);
|
|
||||||
|
|
||||||
let objs5 = document.createElement('input');
|
|
||||||
objs5.setAttribute('type', 'hidden');
|
|
||||||
objs5.setAttribute('name', 'provider');
|
|
||||||
objs5.setAttribute('value', `${user.provider}`);
|
|
||||||
formauth.appendChild(objs5);
|
|
||||||
|
|
||||||
let objs6 = document.createElement('input');
|
|
||||||
objs6.setAttribute('type', 'hidden');
|
|
||||||
objs6.setAttribute('name', 'providerId');
|
|
||||||
objs6.setAttribute('value', `${user.providerId}`);
|
|
||||||
formauth.appendChild(objs6);
|
|
||||||
|
|
||||||
let objs7 = document.createElement('input');
|
|
||||||
objs7.setAttribute('type', 'hidden');
|
|
||||||
objs7.setAttribute('name', 'verify');
|
|
||||||
objs7.setAttribute('value', `${user.verify}`);
|
|
||||||
formauth.appendChild(objs7);
|
|
||||||
|
|
||||||
let objs8 = document.createElement('input');
|
|
||||||
objs8.setAttribute('type', 'hidden');
|
|
||||||
objs8.setAttribute('name', 'agree');
|
|
||||||
objs8.setAttribute('value', `${user.agree}`);
|
|
||||||
formauth.appendChild(objs8);
|
|
||||||
|
|
||||||
formauth.setAttribute('method', 'post');
|
|
||||||
formauth.setAttribute('action', '/authorize/gamepot');
|
|
||||||
document.body.appendChild(formauth);
|
|
||||||
formauth.submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoginFail(error) {
|
|
||||||
const formauth = document.createElement('form');
|
|
||||||
formauth.setAttribute('method', 'post');
|
|
||||||
formauth.setAttribute('action', 'actionsquare://error?errormsg='+ encodeURIComponent(`${error.code}-${error.message}`));
|
|
||||||
document.body.appendChild(formauth);
|
|
||||||
formauth.submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSignInGoogle(error, user) {
|
|
||||||
if (error) {
|
|
||||||
// 로그인 실패
|
|
||||||
onLoginFail(error);
|
|
||||||
} else {
|
|
||||||
onLoginsuccess(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function SignIn(channeltype) {
|
|
||||||
GP.login(channeltype, function (user, error) {
|
|
||||||
if (error) {
|
|
||||||
// 로그아웃 실패
|
|
||||||
onLoginFail(error);
|
|
||||||
} else {
|
|
||||||
// 로그인 성공
|
|
||||||
onLoginsuccess(user)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function Logout() {
|
|
||||||
// GP.logout(function (error) {});
|
|
||||||
GP.logout(function (result, error) {
|
|
||||||
if (error) {
|
|
||||||
// 로그아웃 실패
|
|
||||||
alert(error); // 오류 메세지
|
|
||||||
} else {
|
|
||||||
// 로그아웃 아웃 완료
|
|
||||||
alert("로그아웃 아웃 완료");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteMember() {
|
|
||||||
if (!userId) {
|
|
||||||
alert("로그인을 먼저 해 주세요.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GP.deleteMember(userId, function (result, error) {
|
|
||||||
if (error) {
|
|
||||||
// 회원탈퇴 실패
|
|
||||||
alert(error); // 오류 메세지
|
|
||||||
} else {
|
|
||||||
// 회원탈퇴 아웃 완료
|
|
||||||
alert("회원탈퇴 성공!");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = function () {
|
|
||||||
// 프로젝트 ID는 게임팟 대시보드에서 확인할 수 있습니다.
|
|
||||||
var project_id = "dbfe1334-6dde-43e0-b8a9-cc0733d4c60e";
|
|
||||||
|
|
||||||
var gamepotConfig = {
|
|
||||||
|
|
||||||
api_url: "https://gpapps.gamepot.ntruss.com",
|
|
||||||
google_signin_client_id:
|
|
||||||
"46698421246-aeg0c2pmsgifr3fi06jgnqag5u8ph3kn.apps.googleusercontent.com",
|
|
||||||
google: {
|
|
||||||
callback: onSignInGoogle, // callback 버튼
|
|
||||||
renderButton: "googleRenderButton", // 버튼 DIV 이름
|
|
||||||
option: {
|
|
||||||
// google button option
|
|
||||||
size: "large",
|
|
||||||
theme: "outline",
|
|
||||||
width: "375",
|
|
||||||
text: "signup_with",
|
|
||||||
shape: "rectangular",
|
|
||||||
logo_alignment: "left",
|
|
||||||
locale: "ko_kr"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
facebook_app_id: "2930531180541185",
|
|
||||||
apple_client_id: "auth.service.action2quare.com",
|
|
||||||
apple_redirect_uri: "{{.RedirectBaseUrl}}/authorize/apple",
|
|
||||||
api_key: "b94615af2a956facd2add44ea50529154b35f520de85673d",
|
|
||||||
};
|
|
||||||
|
|
||||||
GP.initialize(project_id, gamepotConfig);
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<div id="googleRenderButton"></div>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<table class="table" border="0" width="400" bgcolor="white" style="table-layout: fixed" onclick="SignIn(GP.ChannelType.APPLE)">
|
|
||||||
<tr>
|
|
||||||
<td align="center">
|
|
||||||
<div
|
|
||||||
id="appleid-signin"
|
|
||||||
data-mode="center-align"
|
|
||||||
data-type="sign-in"
|
|
||||||
data-color="white"
|
|
||||||
data-border="true"
|
|
||||||
data-border-radius="15"
|
|
||||||
data-width="375"
|
|
||||||
data-height="40"
|
|
||||||
data-logo-size="medium"
|
|
||||||
data-logo-position="47"
|
|
||||||
data-label-position="135"
|
|
||||||
style="pointer-events: none"
|
|
||||||
></div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.4 KiB |
276
www/toCDN/gamepot-sdk-javascript-1.0.19-b1.min.js
vendored
276
www/toCDN/gamepot-sdk-javascript-1.0.19-b1.min.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user