Git Product home page Git Product logo

django-simple-sso's Issues

Unable to migrate with Django 1.7

Given that Django 1.7 is no longer supported, I think the action here is to change the README to update the supported version.

The migrations do not work due to a bug in Django 1.7 with the error:
ProgrammingError: (1146, "Table 'your project.sso_server_consumer' doesn't exist")

This is because the default value for private_key on the Consumer model is being calculated, even though Django should be ignoring defaults. The default value in this case is from the SecretKeyGenerator, which queries the database to see if the generated key already exists. Because we are in the migration to create the table, the table isn't there and we get the error.

Newer versions of Django will only get the default value if it is needed

getting error in admin url

django.contrib.admin.sites.AlreadyRegistered: The model Consumer is already registered with 'sso_server.ConsumerAdmin'.

BadRequest at / b'Signature expired'

Hello, I have tried to apply this package, however I have not been successful. I understand the expiration message. But I don't understand why it happens. That is, if I try to log in before 5 seconds.

I appreciate if you can guide me

Authenticate Request fails after successful login

I am trying to set up an authentication system using django-simple-sso. I have followed the Implementation steps mentioned in the readme file. Additionally, I have created a login page for authentication at the django-simple-sso Server.

Environment:

Python - 3.5.3
Database - sqlite
OSX - 10.13.4

Installed Packages:

Django==2.0.5
django-simple-sso==0.13.2

Server Application:

urls.py:

from django.contrib import admin
from django.urls import path, include
from simple_sso.sso_server.server import Server

sso_server = Server()

urlpatterns = [
    path('', include('app.urls')),
    path('admin/', admin.site.urls),
    path('server/', include(sso_server.get_urls())),
]

settings.py:

INSTALLED_APPS = [
    ...
    'simple_sso.sso_server',
]

app/urls.py:

from django.urls import path
from app import views

urlpatterns = [
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
]

app/views.py:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib.auth import login, logout
from app.forms import LoginForm

def login_view(request):
    if request.user.is_authenticated:
        next = request.GET.get('next')
        return HttpResponseRedirect(next)
    else:
        form = LoginForm(request.POST or None)
        if request.POST and form.is_valid():
            user = form.login(request)
            if user:
                login(request, user)
                next = request.GET.get('next')
                return HttpResponseRedirect(next)
        return render(request, 'login.html', {'login_form': form})


def logout_view(request):
    if request.user.is_authenticated:
        logout(request)
    return HttpResponseRedirect('/')

Client credentials are created as mentioned in the Implementation steps.

Server application is run on port http://localhost:8000

Client Application:

urls.py:

from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from simple_sso.sso_client.client import Client

sso_client = Client(settings.SIMPLE_SSO_SERVER, settings.SIMPLE_SSO_KEY, settings.SIMPLE_SSO_SECRET)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('client/', include(sso_client.get_urls())),
]

settings.py:

...
SIMPLE_SSO_SECRET='secret_key'
SIMPLE_SSO_KEY='public_key'
SIMPLE_SSO_SERVER='http://localhost:8000/server/'

Client application is run on port http://localhost:8001

Problem Statement:

When I access the client application url http://localhost:8001/client/

  • Request flows to the server application http://localhost:8000/server/
  • Redirects to http://localhost:8000/login//?next=%2Fserver%2Fauthorize%2F%3Ftoken%3Dsometoken and when I enter the correct username and password, login happens successfully
  • Internally it redirects tohttp://localhost:8000/server/authorize/?token=sometoken and verification request happens http://localhost:8000/server/verify/ and I receive the following error:
Traceback (most recent call last):
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/django/views/generic/base.py", line 89, in dispatch
    return handler(request, *args, **kwargs)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/simple_sso/sso_client/client.py", line 59, in get
    user = self.client.get_user(access_token)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/simple_sso/sso_client/client.py", line 110, in get_user
    user_data = self.consumer.consume(url, data)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/webservices/models.py", line 55, in consume
    body = self.send_request(url, data=signed_data, headers=headers)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/webservices/sync.py", line 13, in send_request
    self.raise_for_status(response.status_code, response.content)
  File "/Users/jagadesh/.virtualenvs/sso_testing/lib/python3.5/site-packages/webservices/models.py", line 67, in raise_for_status
    raise BadRequest(message)
webservices.exceptions.BadRequest: b'Failed to process the request'
[03/May/2018 14:57:59] "GET /client/authenticate/?access_token=IlIzVkcxcjNuak1uRjIxUDE3V0JCTkp2cVdXbGFoNkJidmxqczYwZ3Qycmx0TnF3Q3ZUMmZHcjJ2NWFRV3BscVQi.Dcy09w.ga7zSLKJ4jnbsHUGEaVUB-5m6IM&next=%2F HTTP/1.1" 500 91586

P.S: The Implementation steps along with an example would have been more helpful.

If the server requests the page from the client

I tested the token request from the client to the server, and it passed easily. When I jump from the service side to the client side, it is normally directly passed and does not need to be verified. Has it been implemented, and how can I operate it?

support for https sso server urls

My SSO server is behind an nginx reverse proxy with SSL enabled(self signed). My SSO clients are failing with this error.

Max retries exceeded with url: /server/request-token/ (Caused by SSLErILED] certificate verify failed: self signed certificate (_ssl.c:1076)')))

What can I do to make this connection possible? How can I pass certificate when I call SSO server?

Reverse for 'login' not found. 'login' is not a valid view function or pattern name.

Dears,
when I try to connect from app1/client to app0/server, I got from the server the error:

Reverse for 'login' not found. 'login' is not a valid view function or pattern name.
It comes from

"server.py", line 93, in handle_unauthenticated_user

url = '%s?%s' % (reverse(self.server.auth_view_name), urlencode([('next', next)]))

I tried to create a login view in the server with no results (same error).

what can I do?

thanks in advance!

Propagate new users

Hey there, it's me again!
I came up with this idea due to some discussion on our project regarding application specific user permission handling for new users.
Let me explain the motivation:

Background

  1. sso-server handles user management and user registration
  2. sso-client uses sso-server to check whether a requesting user is a valid, known sso-server user or not
  3. If a new user is registered on the sso-server, the sso-clients are unaware of this user, since they do not share the same database
  4. The new user data is stored on the sso-client on a first login. No local permissions (on the sso-client) could be configured beforehand, since this user was unknown to the sso-client
  5. The user might not have the required privileges and needs to contact the sso-client admin to get the permissions configured properly

Possible solution

There could be a /propagate route on the sso-clients, which takes a request from the sso-server, checks it's authenticity and integrity and then populates the user table with the received data. This would be some kind of shortcut to the regular new-user-adding-on-client-routine, but not having the user logged in. It's only for having a new user written into the client's database before a first login. This gives the admins time to configure needed settings/permissions for this new user.

Discussion

@GaretJax
@FinalAngel
Are there any concerns from your side regarding this idea, before I start implementing and creating a PullRequest? Thanks for your replies in advance, guys!

Content type for responses is text/html

With the default server configuration, the content type for the responses returned by eg RequestTokenProvider is the default (text/html). This seems to be a limitation of provider_for_django() in webservices

On my setup the responses are being mangled by django-htmlmin middleware and I get the error BadTimeSignature, Signature '5gq7ILVLZ5a1TGGhaqFnilRKQw4</body></html>' does not match.

If the content type was text/plain there wouldn't be a problem.

There's a bunch of ways I can work around this for now but it would be good if the content type was set correctly.

need a readme about how to install

new to use django, and when i read about django, the django version is 1.10.
I noticed the project first commit time is 5 years ago, then the django version must very low,
I think It's a very good idea to add Install.txt about how to add this app into django project.

TypeError: manager_method() keywords must be strings

After installing the django-simple-sso and running "python manage.py migrate", this error occurs and I couldn't figure its solution out. Can anyone help me out on this.

while self.get_model().objects.filter(**{self.field: key}).exists():
TypeError: manager_method() keywords must be strings

Update user data

Status quo

  1. Server A, client B, user Bob
  2. Bob opens client B from server A for the first time. His data will be used to create a new User in the client's database.
  3. Bob leaves the client, goes back to server and changes some user data
  4. Bob opens client B from server A again. His data won't be updated in the client's database

Enhancement

The reason is how the build_user method is implemented:

    def build_user(self, user_data):
        try:
            user = User.objects.get(username=user_data['username'])
            # Here should be an update route, which writes all **user_data into the existing user object
        except User.DoesNotExist:
            user = User(**user_data)
        user.set_unusable_password()
        user.save()
        return user

Fails to migrate on MySQL with utf8mb4 charset

The 0002 migration fails with following error:

ERROR Handled exception OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')
  Applying sso_server.0002_consumer_name_max_length...Traceback (most recent call last):
  File "/home/www-data/.local/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/www-data/.local/lib/python3.5/site-packages/django/db/backends/mysql/base.py", line 71, in execute
    return self.cursor.execute(query, args)
  File "/usr/lib/python3/dist-packages/MySQLdb/cursors.py", line 226, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python3/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorvalue
  File "/usr/lib/python3/dist-packages/MySQLdb/cursors.py", line 217, in execute
    res = self._query(query)
  File "/usr/lib/python3/dist-packages/MySQLdb/cursors.py", line 378, in _query
    rowcount = self._do_query(q)
  File "/usr/lib/python3/dist-packages/MySQLdb/cursors.py", line 341, in _do_query
    db.query(q)
  File "/usr/lib/python3/dist-packages/MySQLdb/connections.py", line 280, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')

Feature Request to support django 4.x

Requesting an update on this project. Will there be any support for the django 4.x, The greatest supported version of django is 3.1 and the latest is 4.1

Incompatibility to Django Debug Toolbar

Description

Django-simple-sso seems to be incompatible to the django-debug-toolbar project.

An error is thrown in the ddt middleware, once a client application tries to authenticate a user against the server machine, where the ddt is added to the middlewares.

Reason

The request body contains the signed json content. Ddt always tries to encode this JSON for further analysis, I guess. Due to the structure of the content like

{"x": "y"}.greatSignature

a JsonDecodeError is thrown, since this is no proper json.

Solutions

  1. No solution, just add the hint on the README, that for development (ddt is/should only be used for dev phase) the django debug toolbar needs to be deactivated, when the sso functionality will be used/tested
  2. Refactor the sign-checking functionality into a middleware component, which needs to live at an early stage of the MIDDLEWARE list in the settings.py.

Support multiple websites?

a.com:8000: server
a.com:8001: client1
a.com:8002: client2

i logged on client1
when i visit client2, it will go to server to login, then client1 will auto logout
how to fix it?
thanks

Page Not Found Issue

Hii,
Not Found: /authorize/
[03/Jun/2020 02:04:01] "GET /authorize/?token=2qCFodOLcTZvQ4Pm3WCOW5MnVz3yscUKXWMefOk27Pb6zawVlGIfTah1Ss3oYLJO HTTP/1.1" 404 2534

manager_method() got multiple values for argument 'self'

def save(self,*args,**kwargs):
ex=False
if self.first_name and self.last_name:
to_slug = slugify(str(self.first_name) + " " + str(self.last_name))
ex = Profile.objects.filter(self=to_slug).exists()
while ex:
to_slug = slugify(to_slug + " " + str(get_random_code()))
ex = Profile.objects.filter(self=to_slug).exists()
else:
to_slug = str(self.user)
self.slug = to_slug
super().save(*args,**kwargs)
can anyone help me with this error,whenever i edit the exisiting profile i always get this error

migration file missing?

It seems that a migration file is missing in the package (django-simple-sso==0.13.2, django 1.11, py 3.5)

python manage.py makemigrations --dry-run
venv/lib/python3.5/site-packages/simple_sso/sso_server/migrations/0003_auto_20180405_0822.py
    - Alter field private_key on consumer
    - Alter field public_key on consumer
    - Alter field access_token on token
    - Alter field request_token on token

Error on python 3.5

Hi and thanks for putting your library online! I'm looking forward to use it, it looks really nice.

However, I am encountering two different problems on Django 1.10 and python 2.7 / 3.5 . Here is the error I encounter on python 3.5 .

For which versions of Django beyond 1.7 is simple_sso supposed to work?

File "/var/virtualenvs/machinistgrondverzet/lib/python3.5/site-packages/simple_sso/sso_server/models.py", line 7, in
from ..utils import gen_secret_key
File "/var/virtualenvs/machinistgrondverzet/lib/python3.5/site-packages/simple_sso/utils.py", line 7, in
KEY_CHARACTERS = string.letters + string.digits
AttributeError: module 'string' has no attribute 'letters'

Reverse for 'app_list' not found error on Django 1.10.8, python 2.7.12

Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': u'sso_server'}' not found. 1 pattern(s) tried: [u'admin/(?P<app_label>vouchers|pages|redirects|auth|homepage|mezzanine_blocks|blog|forms|conf|formulieren|videos|galleries|sites|begrippen|generic|registration)/$']


Here is the Traceback:

Environment:

Request Method: GET
Request URL: http://test.go2people.nl:9012/admin/

Django Version: 1.10.8
Python Version: 2.7.12
Installed Applications:
(u'mezzanine.boot',
u'django.contrib.auth',
u'django.contrib.contenttypes',
u'django.contrib.redirects',
u'django.contrib.sessions',
u'django.contrib.sites',
u'django.contrib.sitemaps',
u'mezzanine.conf',
u'mezzanine.core',
u'mezzanine.generic',
u'mezzanine.pages',
u'mezzanine.blog',
u'mezzanine.forms',
u'mezzanine.galleries',
u'mezzanine.twitter',
u'crispy_forms',
u'mezzanine_blocks',
u'registration',
u'simple_sso.sso_server',
u'begrippen',
u'formulieren',
u'homepage',
u'videos',
u'vouchers',
u'zoeken',
u'debug_toolbar',
u'compressor',
u'filebrowser_safe',
u'grappelli_safe',
u'django.contrib.admin',
u'django.contrib.staticfiles',
u'django_comments')
Installed Middleware:
(u'django.contrib.sessions.middleware.SessionMiddleware',
u'django.middleware.locale.LocaleMiddleware',
u'django.middleware.common.CommonMiddleware',
u'django.middleware.csrf.CsrfViewMiddleware',
u'django.contrib.auth.middleware.AuthenticationMiddleware',
u'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
u'django.contrib.messages.middleware.MessageMiddleware',
u'django.middleware.clickjacking.XFrameOptionsMiddleware',
u'mezzanine.core.request.CurrentRequestMiddleware',
u'mezzanine.core.middleware.RedirectFallbackMiddleware',
u'mezzanine.core.middleware.TemplateForDeviceMiddleware',
u'mezzanine.core.middleware.TemplateForHostMiddleware',
u'mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware',
u'mezzanine.core.middleware.SitePermissionMiddleware',
u'mezzanine.pages.middleware.PageMiddleware',
u'vouchers.middleware.VoucherMiddleware',
u'debug_toolbar.middleware.DebugToolbarMiddleware')

Traceback:

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
42. response = get_response(request)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in wrapper
229. return self.admin_view(view, cacheable)(*args, **kwargs)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
211. return view(request, *args, **kwargs)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in index
468. app_list = self.get_app_list(request)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in get_app_list
451. app_dict = self._build_app_dict(request)

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in _build_app_dict
436. current_app=self.name,

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/urls/base.py" in reverse
91. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))

File "/var/virtualenvs/machinistgrondverzet2/local/lib/python2.7/site-packages/django/urls/resolvers.py" in _reverse_with_prefix
392. (lookup_view_s, args, kwargs, len(patterns), patterns)

Exception Type: NoReverseMatch at /admin/
Exception Value: Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': u'sso_server'}' not found. 1 pattern(s) tried: [u'admin/(?P<app_label>vouchers|pages|redirects|auth|homepage|mezzanine_blocks|blog|forms|conf|formulieren|videos|galleries|sites|begrippen|generic|registration)/$']


pip freeze

backports.shutil-get-terminal-size==1.0.0
beautifulsoup4==4.6.0
bleach==2.1.2
certifi==2017.11.5
chardet==3.0.4
confusable-homoglyphs==2.0.2
decorator==4.1.2
Django==1.10.8
django-appconf==1.0.2
django-compressor==2.2
django-contrib-comments==1.8.0
django-crispy-forms==1.7.0
django-debug-toolbar==1.9.1
django-registration==2.3
django-simple-sso==0.11
enum34==1.1.6
filebrowser-safe==0.4.7
future==0.16.0
gevent==1.2.2
grappelli-safe==0.4.7
greenlet==0.4.12
gunicorn==19.7.1
html5lib==1.0.1
idna==2.6
ipdb==0.10.3
ipython==5.5.0
ipython-genutils==0.2.0
itsdangerous==0.24
Mezzanine==4.2.3
-e git://github.com/renyi/mezzanine-blocks.git@2983557c03f16625c63954c4e386915a8eb7e549#egg=mezzanine_blocks
oauthlib==2.0.6
pathlib2==2.3.0
pexpect==4.3.1
pickleshare==0.7.4
Pillow==5.0.0
pkg-resources==0.0.0
prompt-toolkit==1.0.15
psycopg2==2.7.3.2
ptyprocess==0.5.2
Pygments==2.2.0
pytz==2017.3
rcssmin==1.0.6
requests==2.18.4
requests-oauthlib==0.8.0
rjsmin==1.0.12
scandir==1.6
simplegeneric==0.8.1
six==1.11.0
sqlparse==0.2.4
traitlets==4.3.2
tzlocal==1.5.1
urllib3==1.22
wcwidth==0.1.7
webencodings==0.5.1
webservices==0.7
xlrd==1.1.0

Old tokens aren't removed

2yrs after deployment my sso database grown to 16GB. There are tons of old tokens. Some cleaning task would be nice.

Is this project active?

Doubts on server:

simple_sso.server.SimpleSSOServer().get_urls()
or
simple_sso.sso_server.SimpleSSOServer().get_urls()
or 
simple_sso.sso_server.server.Server().get_urls()

Doubts ou client:

simple_sso.sso_client in the client INSTALLED_APPS?

What about the simple_sso.sso_server.models.Client?

 simple_sso.sso_client.client.Client() right?

psycopg2.errors.UndefinedTable: relation "sso_server_consumer" does not exist

I am working on implementing Django-Simple-SSO to our python based platform. I am following this blog to implement SSO:

https://medium.com/@MicroPyramid/django-single-sign-on-sso-to-multiple-applications-64637da015f4

This code is the step number 3 on the server side of django-simple-sso.

from simple_sso.sso_server.models import Token, Consumer

Consumer.objects.create(public_key='your_application_public_key', private_key='your_application_private_key', name='your_application_name')

psycopg2.errors.UndefinedTable: relation "sso_server_consumer" does not exist -- this is the error I am getting as soon as I run the above code in django shell. Can someone please help me on how to solve this error?

I have run both makemigrations and migrate commands. But, still getting the same error.

I am able to see the Consumers table in the django-admin page under the heading SSO_SERVER. But, when I click on that Consumers table, I am getting this error page :

ProgrammingError at /admin/sso_server/consumer/ relation "sso_server_consumer" does not exist LINE 1: SELECT COUNT(*) AS "__count" FROM "sso_server_consumer"
And also why is that Token imported? As it was not used anywhere in that sso blog post.

I have asked this question on stackoverflow as well : https://stackoverflow.com/questions/64281534/psycopg2-errors-undefinedtable-relation-sso-server-consumer-does-not-exist
Thank you

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.