GithubHelp home page GithubHelp logo

gate-sso / gate Goto Github PK

View Code? Open in Web Editor NEW
203.0 203.0 52.0 2.08 MB

Gate is MFA Enabled SSO Platform that supports SAML, OAuth, Linux shell login and CAS

Home Page: https://gate-sso.github.io

License: MIT License

Ruby 78.67% JavaScript 0.37% CoffeeScript 2.21% CSS 0.04% HTML 4.76% Shell 0.34% Dockerfile 0.09% API Blueprint 2.97% SCSS 0.62% Slim 9.93%

gate's People

Contributors

aishwaryark avatar ajeygore avatar codetriage-readme-bot avatar deepsource-autofix[bot] avatar dependabot[bot] avatar detj avatar giosakti avatar kingsly avatar mufti1 avatar olttwa avatar pieterlange avatar prasincs avatar sidpub avatar singhsankalp avatar timusg avatar ujwalendu avatar vjdhama avatar walbertus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gate's Issues

[security] All apis can be accessed using one auth token

Description

  • If one access token is leaked, all apis are compromised.
  • Instead, keep one access token per api.

Acceptance Criteria

  • One access token should authenticate only one api.
  • Access token for an api shouldn't authenticate any other api.

Bulk user deactivation

  • give a list of email
  • ask for confirmation along with additional details like full name, username, etc.

Backend logic:

  • Don't deactivate already deactivated users.

VPN Details page crashing

VPN Details page crashing when ever group id does not match VPN ID, controller method and view does not do right thing.

Also, there are methods distributed across V1 API and older API.

Group management for super admin

Description

A super admin is systems team member who has access to all features of gate. These are the features being added to gate which will be accessible only by super admin:

  • Define groups
  • Add group admin to group
  • Define VPN
  • Add VPNs to a group
  • Add users to a group
  • Add host patterns to a group

Acceptance Criteria

A philosophy we're following for gate is no data ever gets hard deleted. There will be a record of all changes and the person making those changes.

  • A super admin should be able to define groups. There should be a record of who created that.
  • A super admin should be able to add multiple group admin groups. There should be a record of that.
  • A super admin should be able to define a VPN. There should be a record of that.
  • A super adimin should be able to add multiple VPNs to a group. There should be a record of that.
  • A super admin should be able to add users to a group. There should be a record of that.
  • A super admin should be able to add host patterns accessible by users of a group. There should be a record of that.

Regression: Deleteing host patterns from user is broken.

Attempting to delete a host pattern assigned to a user throws the following error page (and doesn't delete the host pattern either.)

The page you were looking for doesn't exist.

You may have mistyped the address or the page may have moved.

If you are the application owner check the logs for more information.

Provide filter for group lists

All group list should provide filter for Only active users and not inactive users, also, prune all inactive members from all the groups.

Implement Auto-complete drop down

We need to provide "writeable" autocomplete drop down with scroll bar, instead of opening entire list, it should just provide place to type.

Authenticate Resources

Authenticate the below resources with an API token
/users/search?q=g
/groups/search?q=g
/host_machines/search?q=g
/vpns/search?q=g

Presently there is no authentication present.

Apart from this also do a check for all calls that aren't web based, that is its api based and apply the api token authentication for it.

Sort VPNs by name.

Sorting VPNs by name on the group page will make it easier for group admins to locate VPNs they have access to.

Show tokens only once and then encrypt and save them and check against encrypted tokens

Here are few changes we need to do for security reasons.

  1. User access token and service access token should be shown or revealed only once, and never again
  2. So when we hit "new" we can send the token, but when we get that back in the form, we should do one-way encryption and then save it, so that this service token cannot be compromised.
  3. We should warn users about this - that you can not see this again.

Better profile page

The profile page is the first page any user (new or returning) sees. I'm referring to /profile.

What do I have in mind?

Well, simple things to start with. Like

  1. Fix typos. Google Authenticator instead of Google Authentication
  2. Structure layout without the use of <br> tags, if possible
  3. Provide links to Google Authenticator Play Store & App Store page
  4. Fix the missing if
  5. ๐Ÿ‘‡

this
profile-before

vs

this
profile-after

  1. Make copy compatible with IPSec VPN, not just OpenVPN

Yeah, if done this. The profile page will be a tad bit better.

host patterns is not wokring

Hi,

I am trying to set it up on my dev server. So up till now, everything works well apart from host pattern.
I have removed access to all host for a particular user and the groups it belongs too i.e host list is empty.
But still that user able to access to that server.
Please let me know if I am missing something.

Fix Caching Logic

If we try to add a user or remove a user from a group, it takes ages to clean that up. we should be able to remove this cache logic and make this group caching much smoother.

Last successful google auth on gate should be tracked

Currently, authentication for all websites takes place without verification of google account status.

  • For authentication+authorization on vpn, ssh, any website, check with GATE.

Acceptance Criteria:

  1. Once a user is logged into gate, there should be a sign-in timestamp somewhere.
  2. While authenticating/authorizing a user, it should be unauthorized if the user is not logged in for past X hours.

Sidenote:

  • Our philosophy for gate is that no data should ever vanish. Should we keep a track of all sign-ins by any user? Currently, we only keep track of last sign-in.

docker-compose dev set-up

  • I should be able to git clone the repo and run docker compose cmd to start the app as well as run rspec
  • Fix Development and Test environments.
    ** Fix docker-compose, Dockerfile, Makefile.
    ** README.md for running tests as well as devlopment.
  • Fix env variables. Use Figaro for env vars. Figaro should be used to check required env vars ahead starting the gate service.

Regression with multiple domain string

The change in 9c6e9be causes an error when ENV['GATE_HOSTED_DOMAINS'] is nil. Example:

rake aborted!
NoMethodError: undefined method `split' for nil:NilClass
/app/config/initializers/devise.rb:16:in `block in (root)'
/usr/local/bundle/gems/devise-4.1.0/lib/devise.rb:280:in `setup'
/app/config/initializers/devise.rb:3:in `<main>'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:1:in `block in (root)'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `load'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `block in load'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/engine.rb:652:in `load_config_initializer'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/notifications.rb:166:in `instrument'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/engine.rb:651:in `block in load_config_initializer'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/engine.rb:616:in `block in Engine'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `run'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/initializable.rb:55:in `block in run_initializers'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/initializable.rb:44:in `tsort_each_child'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/engine.rb:615:in `Engine'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/initializable.rb:54:in `run_initializers'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/application.rb:352:in `<main>'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
/usr/local/bundle/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
/app/config/environment.rb:5:in `(root)'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/application.rb:1:in `block in (root)'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/application.rb:328:in `block in require_environment!'
/usr/local/bundle/gems/railties-4.2.6/lib/rails/application.rb:457:in `run_tasks_blocks'
Tasks: TOP => db:setup => db:schema:load_if_ruby => environment
(See full trace by running task with --trace)
make: *** [db_setup] Error 1

API to authenticate user through saml sso

As an user
I should be able to login to different service providers using gate
So that I get authenticated for the service

  • I should be able to see a login page from gate
  • I should be able to pass my login credentials for authentication
  • On successful authentication, I should get redirected to service or should get a proper error message

Tech Approach

  • Receive SAML request
  • Authenticate the user
  • Generate SAML response for the service provider
  • It should redirects to a redirect url with SAML Response.

Invalid client

Hi, I'm running Gate in a docker-compose setup, and am getting this error in the logs when going through the Oauth flow:

web_1    | I, [2017-07-31T23:46:17.484000 #1]  INFO -- omniauth: (google_oauth2) Request phase initiated.
web_1    | I, [2017-07-31T23:46:17.792000 #1]  INFO -- omniauth: (google_oauth2) Request phase initiated.
web_1    | I, [2017-07-31T23:46:20.194000 #1]  INFO -- omniauth: (google_oauth2) Callback phase initiated.
web_1    | E, [2017-07-31T23:46:21.062000 #1] ERROR -- omniauth: (google_oauth2) Authentication failure! invalid_credentials: OAuth2::Error, invalid_client:
web_1    | {
web_1    |   "error" : "invalid_client"
web_1    | }

I initially had the Oauth credentials set up like this:

# GATE_OAUTH_API_KEY == API key
# GATE_OAUTH_CLIENT_KEY == Oauth client id
# GATE_OAUTH_SECRET == Oauth client secret

which caused an immediate 401 from Google stating:

Error: invalid_client
The OAuth client was not found.

Swapping the API and Client id/key like so:

# GATE_OAUTH_CLIENT_KEY == API key
# GATE_OAUTH_API_KEY == Oauth client id
# GATE_OAUTH_SECRET == Oauth client secret

got me to the point where I could choose a google account to authenticate with, but since I'm now getting an invalid_credentials error, maybe that was the wrong solution.
It's also possible I need to enable additional APIs in the developer console, but that's just a guess.

This is my current .env file (with invalidated credentials):

GATE_OAUTH_CLIENT_KEY=AIzaSyAmRtqnY5mnD2lwvbitQfRijDNOJ34aJCY
GATE_OAUTH_API_KEY=576456017342-jv90rsogj1btmudba64eol381ropol8u.apps.googleusercontent.com
GATE_OAUTH_SECRET=D5_7ZnYl9AwJcWtDYO2FxLwm
GATE_HOSTED_DOMAIN=mydomain.com
GATE_SERVER_URL=gate.mydomain.com
GATE_CONFIG_SECRET=thisismygatessosecret
GATE_EMAIL_DOMAIN=mydomain.com

Do you know what would be causing these invalid_client errors with the credentials in swapped or non-swapped order? Thanks.

Guide for noobs?

I'm trying to setup gate, but I'm an utter noob at these kinds of things and am getting stuck. Could I get some 'noobs guide' on how to set this up with g suite?

As for some concrete questions:

  • What do I need to install prior to installing gate? Mysql? Redis? Anything else?
  • What do the environmental variables mean? The description is quite ambiguous for someone who barely understands how oauth works and #16 confuses me even more. Also "hosted domain for gmail" and "domain for email address" sound like the same thing to me...
  • How can I set this up with a different oauth provider? I don't want to start with our 'production' g suite right away.
  • At least a link to a tutorial on how to setup a rails app with nginx/puma would be nice. All of the ones I found ended with something like "Point puma to your app and you're done", which is exactly the part I don't know how to do...

Additionally, I found that bundle install will fail on mysql with ruby 2.4, but works fine with 2.3.3. Is that intended?

I'm sorry to bother with such stupid questions, but I really like the idea of gate and it seems to be the only thing around allowing this type of setup. The documentation is just way too scarce for me to get it working. I could only find the stuff here on GitHub and then the blog post here. Maybe I missed something...

I'm using Ubuntu Server 16.04 LTS if that matters.

Thanks

callback processing failing with undefined method 'new_session_path'

Hi,

This may be a versioning thing.

I have gate-sso running fine as far as calling out to Google and perfoming the authentication.
But the callback fails with the following error:
I, [2017-06-22T13:40:05.585781 #28966] INFO -- : Processing by Users::OmniauthCallbacksController#failure as HTML
I, [2017-06-22T13:40:05.585869 #28966] INFO -- : Parameters: {"state"=>"a71627ca1b391967fd1f1d31f24c910ce7242c0a3ace090b", "code"=>"4/5YdFdw-hglL9Ve76qMGwIFRaqQzJfqmM_qjDszWCsww"}
I, [2017-06-22T13:40:05.605512 #28966] INFO -- : Completed 500 Internal Server Error in 20ms (ActiveRecord: 0.0ms)
F, [2017-06-22T13:40:05.609879 #28966] FATAL -- :
NoMethodError (undefined method `new_session_path' for #Users::OmniauthCallbacksController:0x0055a61faf52d8

I have tried adding following method (and varients) to application_controller.rb:
def new_session_path(scope)
new_user_session_path
end
but it doesn't help.

I am running with the following gem versions:

devise (4.1.0)
omniauth (1.6.1)
omniauth-google-oauth2 (0.4.1)
omniauth-oauth2 (1.4.0)

Any help appreciated.

Thanks.

API key/access_token management.

Presently Gate allows API keys/access tokens to call any API (and indefinitely.) So a compromised token can be used to make unauthorised calls to all APIs.

  • API keys/access tokens should be linked to a specific API.

  • There should also be an option to have time limited access tokens which will stop working after a specific time.

Multi-domain: When "duplicate" users are present, only authenticate against active users.

While Gate's multi-domain support expects usernames to be unique across domains. it isn't strictly enforced at the moment.

This allows for the following situation.

USER1 - [email protected] INACTIVE
USER2 - [email protected] ACTIVE

Present behaviour:

While USER2 is active and able to login to gate with their Google account, but when authenticating against gate, gate only checks the oldest user irrespective of "active" status, so [email protected] will never get a successful auth, even though they exist on gate and are the only active user at present.

Expected behavior:

Gate should check for "active" users with a particular username and authenticate them.

(Ideally Gate should also prevent such situations from arising in the first place, which will be addressed as a different issue for that but this fix will allow existing installations to work with minimal change in gate auth logic. )

VPN Configuration file for user

Description

A user should be able to download the configuration for all VPNs he/she has access to from gate profile page

Acceptance criteria

  • All VPNs authorized for a user should be added to the VPN configuration file
  • When access for a VPN has been revoked for a user, it should reflect in the conf file.

bundle exec rake db:create db:migrate db:seed fails duo to SAML missing env vars

Hi

when trying to setup gate-oss using the README documentation It fails on the following step:
bundle exec rake db:create db:migrate db:seed with the following error message:

NoMethodError: undefined method `gsub' for nil:NilClass
/srv/app/gate/config/initializers/saml_idp.rb:6:in `block in <top (required)>'
/srv/app/gate/vendor/bundle/ruby/2.3.0/bundler/gems/saml_idp-cd646cbb9baf/lib/saml_idp.rb:18:in `configure'
/srv/app/gate/config/initializers/saml_idp.rb:1:in `<top (required)>'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `load'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `block in load'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in `load'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:652:in `block in load_config_initializer'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb:166:in `instrument'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:651:in `load_config_initializer'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:616:in `block (2 levels) in <class:Engine>'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:615:in `each'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:615:in `block in <class:Engine>'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `instance_exec'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `run'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:55:in `block in run_initializers'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:44:in `each'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:44:in `tsort_each_child'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:54:in `run_initializers'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application.rb:352:in `initialize!'
/srv/app/gate/config/environment.rb:5:in `<top (required)>'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application.rb:328:in `require_environment!'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application.rb:457:in `block in run_tasks_blocks'
/srv/app/gate/vendor/bundle/ruby/2.3.0/gems/rake-12.1.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => db:migrate => environment

I think that the environment variable GATE_SAML_IDP_X509_CERTIFICATE and GATE_SAML_IDP_SECRET_KEY should be set but can't find any information about it.

VPN user management

description

VPN is a single host which connects to a VPC network.

  • Super admin assigns VPNs to groups
  • Group admin assigns VPNs assigned to them to users in their group

Assign users to group via API

  • As developer of external service which utilizes gate
  • I want to be able to assign users in my service to a group in gate
  • Gate should provide API for assigning and removing users from a group

@ajeygore, There are some services depends on Gate API to assign/remove user from group. It used to exist on nss_controller#add_user_to_group.

How can these external services do it now? should I create a new API?

Gate should handle sessions locally

Presently gate manages sessions for users logging in to gate, but the flip-side of this is that even when the APIs are called or gate authentication via CAS these sessions are used.

This shouldn't be the approach both of them needed to be treated separately.

  • APIs should be validated via a token. Tokens to be supported are User Tokens, Application Tokens
  • Gate Login for users, group admin and admin to manage their gate account
  • CAS / SAML which shouldn't effect their Gate Local Session

The problems that have been faced, when I am integrating CAS / SAML I need to logout of my internal application. I am forced to go to gate logout and then get logged out of my application.

Generating saml metadata

As a gate SAML consumer I should be able to generate metadata.xml for different service providers so that this metadata.xml file can be uploaded to respective service provide. I should have an api for generating metadata.

Define user roles in gate

I as an admin, want to create user categories and admin roles for users so that admins can manage their respective user groups and their access to integration/production environment as required.

Acceptance Criteria :

  • Users should be classified into 4 categories - Super Admin, Group Admin, IT Admin and Users
  • Every user with a valid and approved google account is a user by default
  • Super Admin privileges will rest with Systems team
  • IT Admin and Group Admin privileges will need to be enabled by super admin.

Some VPNs shows up twice

Some VPNs show up twice with group list and user list, please provide a way to make vpn list uniq.

Revoke host pattern

Description

Given a host pattern, disable/revoke access for all users.

Acceptance criteria

  • Given a host pattern, no user should have access to all the hosts matching that host pattern

Restricting VPN profile creation to certain users

Hi! This may be a noob question. Is it possible to restrict create of vpn profiles to only certain users if using Google Authentication? I would like to have approved users be able to automatically have profiles created, but only approved users. Thanks!

DB Bottleneck on Some APIs

Due to gate database crashing because of huge number of requests from clients with gate-nss-cache and other services which intensely calls nss_controller#group, I profiled the APIs called by them and found N+1 query that we can rewrite and mysql indexes that we can introduce to improve performance.

We can also add even more Redis cache to keep gate from hitting db.

So these are the actions that I wanna take:

  • 1. Low-hanging fruit patches: rewrite N+1 query and add some indexes based on mysql ANALYZE
  • 2. Introduce more redis cache to nss_controller#group, nss_controller#passwd and nss_controller#group_list whenever possible

Group management for group admins

Description

Group admins will handle all authorization for users of a group. Every group will have only one admin who'll fulfill the following responsibilities:

  • add/remove access to users for VPN/s
  • remove users from their group
  • add/remove access to users based on host name/patterns

Acceptance Criteria

A philosophy we're following for gate is no data ever gets hard deleted. There will be a record of all changes and the person making those changes.

  • A group admin should be able to add access to users for VPNs
  • A group admin should be able to remove access to users for VPNs
  • A group admin should be able to remove users from groups
  • A group admin should be able to add users based on host name/patterns
  • A group admin should be able to remove users based on host name/patterns
  • There should be a record of all above functions

Flash message shown at wrong place

Signed out successfully message shows up at an incorrect time & place.

gate gojek co id_api_resources_new

Steps to reproduce

  1. Login
  2. Sign out
  3. Login again
  4. Navigate to /api_resources/new

Expected behavior

Maybe it just doesn't make sense to show this message anywhere. The signout operation anyways performs a redirect and lands the user on the (logged-out) landing screen. So, for a user its quite clear, that sign out was a success.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.