New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Closed
edwint88 opened this issue
Apr 26, 2022
· 15 comments
Closed
Import Realm in Keycloak 18.0.0 — failed
#11664
edwint88 opened this issue
Apr 26, 2022
· 15 comments
Comments
Describe the bug
I’m using a docker image and I uploaded the realm.json in /opt/keycloak/data/import
to get the nice auto import functionality.
When I add now to start —import-realm I get:
2022-04-26 08:28:56,195 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (production) mode
2022-04-26 08:28:56,195 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to import realm: myrealm
2022-04-26 08:28:56,195 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Script upload is disabled
which confuses me, because
Script Upload should be removed (why is import using that?) and
doesn’t work.
Without the --import-realm
all works fine
Reference to documentation: https://www.keycloak.org/server/importExport
Version
18.0.0
Expected behavior
To import the realms automatically from the data/import
location.
Actual behavior
Gives an error
How to Reproduce?
- create a dockerfile
- add a realm.json to the path
- build keycloak in docker file
- build dockerfile
- start container
Anything else?
No response
Copy link
Contributor
Author
The same error I get also when I try to upload a realm from the interface/admin console:
Uncaught server error: java.lang.RuntimeException: Script upload is disabled
Linking this discussion I opened a few ago: #11658
Copy link
Contributor
Author
@edwint88 Is your realm declaring providers that rely on scripts such as mappers, authenticators, or policies?
If so, the realm configuration is now invalid and you should not be able to import. See the note here about the removal of the upload-scripts
feature.
@edwint88 Is your realm declaring providers that rely on scripts such as mappers, authenticators, or policies?
I had the same issue and based on your feedback I search and found I had these policies for one of the realm clients:
"policies": [ { "id": "b56eebd7-8e73-4449-b110-30dfdbc77f03", "name": "Default Policy", "description": "A policy that grants access only for users within this realm", "type": "js", "logic": "POSITIVE", "decisionStrategy": "AFFIRMATIVE", "config": { "code": "// by default, grants any permission associated with this policyn$evaluation.grant();n" } }, { ... }, { "id": "1428ae4c-b767-41b9-aaf9-bd8b0d8497e2", "name": "Default Permission", "description": "A permission that applies to the default resource type", "type": "resource", "logic": "POSITIVE", "decisionStrategy": "UNANIMOUS", "config": { "defaultResourceType": "urn:api:resources:default", "applyPolicies": "["Default Policy"]" } }, {...} ]
I checked and these were not referenced anywhere else so I proceeded to delete them and it worked.
I guess it was created automatically by a previous version of KC.
For anyone else experiencing the same issue: search for "type": "js"
to pin-point the root cause in the realm export file.
FelipeMaeda, lalitjeevanrao, Natanaelvich, dryleaf, FedericoHeichou, gregorkistler, axi92, agustinbravop, douph1, cordosvictor, and 4 more reacted with heart emoji
Copy link
Contributor
Author
«> @edwint88 Is your realm declaring providers that rely on scripts such as mappers, authenticators, or policies?
If so, the realm configuration is now invalid and you should not be able to import. See the note here about the removal of the
upload-scripts
feature.
We have an Authenticator, but not a JavaScript one. It’s a simple Java SPI that we add through .jar in /opt/keycloak/providers
and then, yes, configured in the realm.json.
Is this affected too?
LE: thanks for the "type": "js"
hint!
we got a default policy — that we didn’t create it, I’ll check without that in the config.
{ "id": "cf9f7684-45c2-4bcd-89a5-38c2a41b55fd", "name": "Default Policy", "description": "A policy that grants access only for users within this realm", "type": "js", "logic": "POSITIVE", "decisionStrategy": "AFFIRMATIVE", "config": { "code": "// by default, grants any permission associated with this policyn$evaluation.grant();n" } }
That was the problem! So when I’ve created a dummy confidential client in 17.0.1 the Default JS policies were activated!
Copy link
Contributor
Author
Hi,
Deleting the default policies is safe. Later on you want to have your own
there. The error I think is still relate to the js thing, because if you
delete just that policy some reference will remain to it and therefore will
fail your import.
Cheers
…
On Mon, Jul 11, 2022, 13:34 ericwout-overheid ***@***.***> wrote:
We would like to reopen this discussion. We are just starting with a
project using Keycloak (18.0.2). We have create a realm via the user
interface with some basic settings. We exported the realm using the Manage
> Export > Partial Export feature in the user interface.
When we try to import this export using the —import-realm option in a
clean container (also 18.0.2), we get the mentioned error. It seems like a
bug when Keycloak does not generate a compatible export for the same
version?
It works when we remove the policies element enterily (not when we only
remove the policy with the «js»-type). But as new users we are not sure
whether that’s a safe thing to do.
—
Reply to this email directly, view it on GitHub
<#11664 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAV67TIICGL7DHKCGE3CYTTVTQBF3ANCNFSM5ULDLUPA>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
Ah, thanks for clearing that up. But shouldn’t it be registered as a bug that when you create an export, it cannot be imported without removing this by hand (after googling for it?).
Copy link
Contributor
Author
Sure, I don’t know if there is a ticket already or to be fixed in the next version.
Change the default policy type to the script-jsfilename:
{
"id": "834d0278-8eda-4533-911b-78a1d983ffc9",
"name": "Default Policy",
"description": "A policy that grants access only for users within this realm",
"type": "script-default-policy.js",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE"
},
put the jar to providers, then
kc.sh build
and
kc.sh start
.
The default-policy.js in one sample jar photoz-uma-js-policies.jar.
photoz-uma-js-policies.jar
shouldn’t it be registered as a bug that when you create an export, it cannot be imported without removing this by hand
I agree, this issue should be re-opened, this problem still exists in keycloak 20.0
The workaround described above seems to still work (using the quay.io/keycloak/keycloak
docker image), here is a minimal, reproducible example of the issue and the workaround:
- Start an interactive docker container:
docker run --name auth1 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=12345 -it --entrypoint=/bin/bash -p 8080:8080 quay.io/keycloak/keycloak:20.0
- Start the keycloak service:
/opt/keycloak/bin/kc.sh start-dev
- From the host or another system, login to
localhost:8080
after it spins up and create the realm, users, clients, etc. as one sees fit, for this example, the realm will bemyrealm
- Stop the keycloak service (e.g. CTRL-C)
- Export the realm:
/opt/keycloak/bin/kc.sh export --realm myrealm --users same_file --file /tmp/realm-export.json.tmp
- Exit the docker instance and let it stop
exit
- Copy the exported realm out of the docker instance to a temporary file:
docker cp auth1:/tmp/realm-export.json.tmp realm-export.json.tmp
- Copy said temporary file to an
import
folder:cp realm-export.json.tmp import/realm-export.json
- Verify import bug still exists by attempting to import said realm upon container instance spinup:
$ docker run --name auth2 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=12345 -v $(pwd)/import/:/opt/keycloak/data/import/:ro --rm quay.io/keycloak/keycloak:20.0 start-dev --import-realm
...
Unable to import realm myrealm from file /opt/keycloak/bin/../data/import/realm-export.json.: java.lang.RuntimeException: Script upload is disabled
- Stop the service with CTRL-C and let the docker instance exit and remove itself
- Remove the policies using
jq
to avoid editing by hand:cat realm-export.json.tmp | jq 'del(.clients[].authorizationSettings.policies)' > import/realm-export.json
- Verify import now works:
docker run --name auth2 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=12345 -v $(pwd)/import/:/opt/keycloak/data/import/:ro --rm -p 8080:8080 quay.io/keycloak/keycloak:20.0 start-dev --import-realm
Replacing the Default Policy
setting with the one below resolves the issue and maintains the expected behavior.
{ "id": "98bb844e-5524-4c42-914b-cc5121d3124d", "name": "Default Policy", "description": "A policy that grants access only for users within this realm", "type": "role", "logic": "POSITIVE", "decisionStrategy": "AFFIRMATIVE", "config": { "roles": "[{"id":"default-roles-main","required":false}]" } }
script-default-policy.js
@yangboyd this works
put the jar to providers, then
kc.sh build
and
kc.sh start
.
The default-policy.js in one sample jar photoz-uma-js-policies.jar.
photoz-uma-js-policies.jar
But the problem is with upgrade from wildfly(15) distro to keycloak(20) , as in database have of type js entry for default policy.
And we can not ask end user/admin to change the type of Policy type.
What is the recommendation in the scenarios of migration?
Skip to navigation
Skip to main content
Infrastructure and Management
- Red Hat Enterprise Linux
- Red Hat Virtualization
- Red Hat Identity Management
- Red Hat Directory Server
- Red Hat Certificate System
- Red Hat Satellite
- Red Hat Subscription Management
-
Red Hat Update Infrastructure
- Red Hat Insights
- Red Hat Ansible Automation Platform
Cloud Computing
- Red Hat OpenShift
- Red Hat CloudForms
- Red Hat OpenStack Platform
- Red Hat OpenShift Container Platform
- Red Hat OpenShift Data Science
- Red Hat OpenShift Online
- Red Hat OpenShift Dedicated
- Red Hat Advanced Cluster Security for Kubernetes
-
Red Hat Advanced Cluster Management for Kubernetes
- Red Hat Quay
- OpenShift Dev Spaces
- Red Hat OpenShift Service on AWS
Storage
- Red Hat Gluster Storage
- Red Hat Hyperconverged Infrastructure
- Red Hat Ceph Storage
- Red Hat OpenShift Data Foundation
Runtimes
- Red Hat Runtimes
- Red Hat JBoss Enterprise Application Platform
-
Red Hat Data Grid
- Red Hat JBoss Web Server
- Red Hat Single Sign On
- Red Hat support for Spring Boot
- Red Hat build of Node.js
- Red Hat build of Thorntail
- Red Hat build of Eclipse Vert.x
- Red Hat build of OpenJDK
- Red Hat build of Quarkus
Integration and Automation
- Red Hat Process Automation
-
Red Hat Process Automation Manager
- Red Hat Decision Manager
All Products
Issue
- The deprecation of upload_scripts feature prevents Import/Export Authorization Settings from any openid-connect client with the following exception:
ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-7) Uncaught server error: java.lang.RuntimeException: Script upload is disabled
at org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.updatePolicy(JSPolicyProviderFactory.java:125)
at org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.onImport(JSPolicyProviderFactory.java:70)
at org.keycloak.models.utils.RepresentationToModel.toModel(RepresentationToModel.java:2185)
at org.keycloak.models.utils.RepresentationToModel.importPolicies(RepresentationToModel.java:2113)
at org.keycloak.models.utils.RepresentationToModel.toModel(RepresentationToModel.java:2059)
at org.keycloak.authorization.admin.ResourceServerService.importSettings(ResourceServerService.java:136)
-
We need to be able to export client configuration data from one RH-SSO instance and import it to another instance.
-
Exporting and then importing realm in RH-SSO fails with following error
ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-3) Uncaught server error: java.lang.RuntimeException: Script upload is disabled
at org.keycloak.keycloak-authz-policy-common@18.0.0.redhat-00001//org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.throwCanNotUpdatePolicy(JSPolicyProviderFactory.java:130)
at org.keycloak.keycloak-authz-policy-common@18.0.0.redhat-00001//org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.onImport(JSPolicyProviderFactory.java:72)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.models.utils.RepresentationToModel.toModel(RepresentationToModel.java:2483)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.authorization.AuthorizationProvider$3.create(AuthorizationProvider.java:351)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.models.utils.RepresentationToModel.importPolicies(RepresentationToModel.java:2405)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.models.utils.RepresentationToModel.toModel(RepresentationToModel.java:2353)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.models.utils.RepresentationToModel.importAuthorizationSettings(RepresentationToModel.java:2300)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.models.utils.RepresentationToModel.lambda$importRealmAuthorizationSettings$9(RepresentationToModel.java:2278)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.keycloak.keycloak-server-spi-private@18.0.0.redhat-00001//org.keycloak.models.utils.RepresentationToModel.importRealmAuthorizationSettings(RepresentationToModel.java:2276)
Environment
- Red Hat Single Sign-On (RH-SSO)
- 7.3
- 7.4
- 7.5
- 7.6
Subscriber exclusive content
A Red Hat subscription provides unlimited access to our knowledgebase, tools, and much more.
Current Customers and Partners
Log in for full access
Log In
Клонируем репозиторий с чартом:
mkdir ~/keycloak && cd ~/keycloak git clone https://github.com/codecentric/helm-charts.git echo '' > helm-charts/charts/keycloak/requirements.yaml
user@postgres:~$ sudo su - postgres postgres@postgres:~$ psql postgres=# create database keycloak; CREATE DATABASE postgres=# create user keycloak with encrypted password 'keycloak_db_password'; CREATE ROLE postgres=# grant all privileges on database keycloak to keycloak; GRANT
Создаем неймспейс
kubectl create ns keycloak
Создаем секреты с дефолтным паролем админской учетки keycloak и паролем пользователя базы данных:
kubectl create secret generic keycloak-default-admin-password -n keycloak --from-literal=password=keycloak_console_password kubectl create secret generic keycloak-db-password -n keycloak --from-literal=password=keycloak_db_password --from-literal=username=keycloak
Создаем секрет с ssl-сертификатом web-интерфейса:
openssl pkcs12 -in sso.domain.local.pfx -nocerts -out sso.domain.local.key openssl rsa -in sso.domain.local.key -out sso.domain.local.key.pem openssl pkcs12 -in sso.domain.local.pfx -clcerts -nokeys -out sso.domain.local.cert.crt kubectl create secret generic -n keycloak sso-domain-local --from-file=tls.crt=./sso.domain.local.cert.crt --from-file=tls.key=./sso.domain.local.key.pem
Создаем ConfigMap с корпоративными корневыми сертификатами. Они должны быть в формате pem и оформлены стандартными разделителями — —–BEGIN CERTIFICATE—– и —–END CERTIFICATE—–.
kubectl -n keycloak create configmap ca-bundle --from-file=./ca.cer
keycloak: replicas: 1 image: tag: 8.0.2 existingSecret: "keycloak-default-admin-password" extraVolumes: | - name: ca-bundle configMap: name: ca-bundle extraVolumeMounts: | - name: ca-bundle mountPath: /custom_certs/ extraEnv: | - name: X509_CA_BUNDLE value: "/custom_certs/ca.cer" - name: PROXY_ADDRESS_FORWARDING value: "true" - name: JAVA_OPTS value: | -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Dkeycloak.profile.feature.upload_scripts=enabled ingress: enabled: true path: / annotations: kubernetes.io/ingress.class: nginx hosts: - sso.domain.local tls: - hosts: - sso.domain.local secretName: sso-domain-local persistence: deployPostgres: false dbVendor: "postgres" existingSecret: "keycloak-db-password" dbName: keycloak dbHost: 10.10.10.10 dbPort: 5432 test: enabled: false
При обновлении с версии 8.0.2 до версии 9.0.3 в логах возникла ошибка:
16:11:15,512 INFO [org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider] (ServerService Thread Pool -- 68) Updating database. Using changelog META-INF/jpa-changelog-master.xml 16:11:15,595 ERROR [org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider] (ServerService Thread Pool -- 68) Change Set META-INF/jpa-changelog-9.0.1.xml::9.0.1-KEYCLOAK-12579-add-not-null-constraint::keycloak failed. Error: ERROR: duplicate key value violates unique constraint "sibling_names" Detail: Key (realm_id, parent_group, name)=(rdleas, , 1_SrvDocs_DocumentationAIB_Owner) already exists. [Failed SQL: UPDATE public.KEYCLOAK_GROUP SET PARENT_GROUP = ' ' WHERE PARENT_GROUP IS NULL] 16:11:15,602 FATAL [org.keycloak.services] (ServerService Thread Pool -- 68) java.lang.RuntimeException: Failed to update database
Судя по всему — в базе две записи о группе 1_SrvDocs_DocumentationAIB_Owner.
Сначала — останавливаем keycloak. для этого редактируем statefullSet и ставим replicas: 0
Идем на сервер postgres, перевоплощаемся в пользователя postgres:
sudo su - postgres
и лечим. Для начала — восстановим базу из бекапа в исходное состояние:
dropdb keycloak createdb keycloak psql -d keycloak -f ./keycloak_10.06.20_15-03.bak
Дальше запускаем psql и смотрим список баз:
l
Переключаемся на базу keycloak:
c keycloak
Убеждаемся, что записей о группе две:
SELECT * FROM public.KEYCLOAK_GROUP WHERE name = '1_SrvDocs_DocumentationAIB_Owner';
Непонятно, какая из них правильная — удаляем обе:
DELETE FROM public.KEYCLOAK_GROUP WHERE name = '1_SrvDocs_DocumentationAIB_Owner';
Протестировать keycloak и убедиться, что он настроен правильно и работает можно с помощью простых приложений.
https://gist.github.com/thomasdarimont/145dc9aa857b831ff2eff221b79d179a (https://gist.githubusercontent.com/thomasdarimont/145dc9aa857b831ff2eff221b79d179a/raw/a72a9462b2bd693913efba86cbc74f87c043121d/app.py)
https://gist.githubusercontent.com/thomasdarimont/145dc9aa857b831ff2eff221b79d179a/raw/a72a9462b2bd693913efba86cbc74f87c043121d/client_secrets.json
Ставим то что нужно:
sudo pip3 --trusted-host pypi.org --trusted-host files.pythonhosted.org --proxy=http://127.0.0.1:3130 install flask flask_oidc cherrypy cryptojwt cryptography>=2.8
Тестовое приложение на фреймворке flask — app.py.
#!/usr/bin/env python3 import json import logging from flask import Flask, g from flask_oidc import OpenIDConnect import requests logging.basicConfig(level=logging.DEBUG) app = Flask(__name__) app.config.update({ 'SECRET_KEY': 'SomethingNotEntirelySecret', 'TESTING': True, 'DEBUG': True, 'OIDC_CLIENT_SECRETS': 'client_secrets.json', 'OIDC_ID_TOKEN_COOKIE_SECURE': False, 'OIDC_REQUIRE_VERIFIED_EMAIL': False, 'OIDC_USER_INFO_ENABLED': True, 'OIDC_OPENID_REALM': 'flask-demo', 'OIDC_SCOPES': ['openid', 'email', 'profile'], 'OIDC_INTROSPECTION_AUTH_METHOD': 'client_secret_post' }) oidc = OpenIDConnect(app) @app.route('/') def hello_world(): if oidc.user_loggedin: return ('Hello, %s, <a href="/private">See private</a> ' '<a href="/logout">Log out</a>') % oidc.user_getfield('preferred_username') else: return 'Welcome anonymous, <a href="/private">Log in</a>' @app.route('/private') @oidc.require_login def hello_me(): """Example for protected endpoint that extracts private information from the OpenID Connect id_token. Uses the accompanied access_token to access a backend service. """ info = oidc.user_getinfo(['preferred_username', 'email', 'sub', 'groups']) username = info.get('preferred_username') email = info.get('email') user_id = info.get('sub') groups = info.get('groups') greeting = 'Greeting!!!' """if user_id in oidc.credentials_store: try: from oauth2client.client import OAuth2Credentials access_token = OAuth2Credentials.from_json(oidc.credentials_store[user_id]).access_token print ('access_token=<%s>' % access_token) headers = {'Authorization': 'Bearer %s' % (access_token)} # YOLO # greeting = requests.get('http://localhost:8080/greeting', headers=headers).text except: print ("Could not access greeting-service") greeting = "Hello %s" % username """ return (""" %s </br> Your email is %s </br> Your user_id is %s! </br> Your Groups - %s </br> <ul> <li><a href="/">Home</a></li> <li><a href="https://sso.rdleas.ru/auth/realms/rdleas/account?referrer=flask-app&referrer_uri=http://192.168.104.94:5000/private&">Account</a></li> </ul>""" % (greeting, email, user_id, groups)) @app.route('/api', methods=['POST']) @oidc.accept_token(require_token=True, scopes_required=['openid']) def hello_api(): """OAuth 2.0 protected API endpoint accessible via AccessToken""" return json.dumps({'hello': 'Welcome %s' % g.oidc_token_info['sub']}) @app.route('/logout') def logout(): """Performs local logout by removing the session cookie.""" oidc.logout() return 'Hi, you have been logged out! <a href="/">Return</a>' if __name__ == '__main__': app.run(host= '0.0.0.0') # app.run()
И конфигурационный файл для него — client_secrets.json
{ "web": { "issuer": "https://sso.rdleas.ru/auth/realms/rdleas", "auth_uri": "https://sso.rdleas.ru/auth/realms/rdleas/protocol/openid-connect/auth", "client_id": "test", "client_secret": "32e8263a-9edc-4159-902a-e23c22606b1d", "redirect_uris": [ "http://192.168.104.94:5000/*" ], "userinfo_uri": "https://sso.rdleas.ru/auth/realms/rdleas/protocol/openid-connect/userinfo", "token_uri": "https://sso.rdleas.ru/auth/realms/rdleas/protocol/openid-connect/token", "token_introspection_uri": "https://sso.rdleas.ru/auth/realms/rdleas/protocol/openid-connect/token/introspect" } }
Запускаем так:
./app.py
Вот еще один ваиант тестового приложения. Но его запуск я не осилил.
git clone https://github.com/openid/JWTConnect-Python-OidcRP.git cd ./JWTConnect-Python-OidcRP/chrp cp ./example_conf.py ./conf.py ./make_opbyuid_html.py conf > html/opbyuid.html sudo pip3 --trusted-host pypi.org --trusted-host files.pythonhosted.org --proxy=http://127.0.0.1:3130 install cherrypy cryptojwt cryptography>=2.8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.