def ldap_create_user(user_info): """takes the result returned by the :func:`ldap_authenticate` and returns a :class:`UserAssociation` object """ # create new user in local db user = User() user.username = user_info.get('django_username', user_info['ldap_username']) user.set_unusable_password() user.first_name = user_info['first_name'] user.last_name = user_info['last_name'] user.email = user_info['email'] user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user = user) LOG.info('Created New User : [{0}]'.format(user_info['ldap_username'])) assoc = UserAssociation() assoc.user = user assoc.openid_url = user_info['ldap_username'] assoc.provider_name = 'Wind River LDAP' assoc.save() return assoc
def cas_get_or_create_user(cas_response): """takes the result returned by the :func:`ldap_authenticate` and returns a :class:`UserAssociation` object """ # create new user in local db try: logging.debug("Getting user association for %s", cas_response.get('user')) assoc = UserAssociation.objects.get( openid_url = cas_response.get('user') + '@ldap', provider_name = 'ldap' ) return assoc except UserAssociation.DoesNotExist: try: user = User.objects.get(username=cas_response.get('user')) except User.DoesNotExist: user = User() user.username = cas_response.get('django_username', cas_response.get('user')) user.set_unusable_password() user.first_name = cas_response['attributes'].get('firstName', None) user.last_name = cas_response['attributes'].get('lastName', None) user.email = cas_response['attributes'].get('email', None) user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user = user) logging.debug('Created New User : [{0}]'.format(cas_response.get('user'))) assoc = UserAssociation() assoc.user = user assoc.openid_url = cas_response.get('user') + '@ldap' assoc.provider_name = 'ldap' assoc.save() return assoc
def create_authenticated_user_account( username=None, email=None, password=None, user_identifier=None, login_provider_name=None, subscribe=False ): """creates a user account, user association with the login method and the the default email subscriptions """ user = User.objects.create_user(username, email) user_registered.send(None, user=user) logging.debug('creating new openid user association for %s') if password: user.set_password(password) user.save() else: UserAssociation( openid_url = user_identifier, user = user, provider_name = login_provider_name, last_used_timestamp = datetime.datetime.now() ).save() subscribe_form = askbot_forms.SimpleEmailSubscribeForm( {'subscribe': subscribe} ) subscribe_form.full_clean() logging.debug('saving email feed settings') subscribe_form.save(user) logging.debug('logging the user in') user = authenticate(method='force', user_id=user.id) if user is None: error_message = 'please make sure that ' + \ 'askbot.deps.django_authopenid.backends.AuthBackend' + \ 'is in your settings.AUTHENTICATION_BACKENDS' raise Exception(error_message) return user
def create_authenticated_user_account(username=None, email=None, password=None, user_identifier=None, login_provider_name=None, subscribe=False): """creates a user account, user association with the login method and the the default email subscriptions """ user = User.objects.create_user(username, email) user_registered.send(None, user=user) logging.debug('creating new openid user association for %s') if password: user.set_password(password) user.save() else: UserAssociation(openid_url=user_identifier, user=user, provider_name=login_provider_name, last_used_timestamp=datetime.datetime.now()).save() subscribe_form = askbot_forms.SimpleEmailSubscribeForm( {'subscribe': subscribe}) subscribe_form.full_clean() logging.debug('saving email feed settings') subscribe_form.save(user) logging.debug('logging the user in') user = authenticate(method='force', user_id=user.id) if user is None: error_message = 'please make sure that ' + \ 'askbot.deps.django_authopenid.backends.AuthBackend' + \ 'is in your settings.AUTHENTICATION_BACKENDS' raise Exception(error_message) return user
def ldap_authenticate(username, password): """ Authenticate using ldap python-ldap must be installed http://pypi.python.org/pypi/python-ldap/2.4.6 """ import ldap user_information = None try: ldap_session = ldap.initialize(askbot_settings.LDAP_URL) ldap_session.protocol_version = ldap.VERSION3 user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD, username) # search ldap directory for user res = ldap_session.search_s(askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, None) if res: # User found in LDAP Directory user_dn = res[0][0] user_information = res[0][1] ldap_session.simple_bind_s(user_dn, password) # <-- will throw ldap.INVALID_CREDENTIALS if fails ldap_session.unbind_s() exact_username = user_information[askbot_settings.LDAP_USERID_FIELD][0] # Assuming last, first order # --> may be different last_name, first_name = user_information[askbot_settings.LDAP_COMMONNAME_FIELD][0].rsplit(" ", 1) email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0] try: user = User.objects.get(username__exact=exact_username) # always update user profile to synchronize with ldap server user.set_password(password) user.first_name = first_name user.last_name = last_name user.email = email user.save() except User.DoesNotExist: # create new user in local db user = User() user.username = exact_username user.set_password(password) user.first_name = first_name user.last_name = last_name user.email = email user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user = user) log.info('Created New User : [{0}]'.format(exact_username)) return user else: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None except ldap.INVALID_CREDENTIALS, e: return None # Will fail login on return of None
def authenticate( self, username = None,#for 'password' and 'ldap' password = None,#for 'password' and 'ldap' user_id = None,#for 'force' provider_name = None,#required with all except email_key openid_url = None, email_key = None, oauth_user_id = None,#used with oauth facebook_user_id = None,#user with facebook wordpress_url = None, # required for self hosted wordpress wp_user_id = None, # required for self hosted wordpress method = None,#requried parameter ): """this authentication function supports many login methods just which method it is going to use it determined from the signature of the function call """ login_providers = util.get_enabled_login_providers() assoc = None # UserAssociation not needed for ldap if method == 'password': if login_providers[provider_name]['type'] != 'password': raise ImproperlyConfigured('login provider must use password') if provider_name == 'local': try: user = User.objects.get(username=username) if not user.check_password(password): return None except User.DoesNotExist: try: email_address = username user = User.objects.get(email = email_address) if not user.check_password(password): return None except User.DoesNotExist: return None except User.MultipleObjectsReturned: logging.critical( ('have more than one user with email %s ' + 'he/she will not be able to authenticate with ' + 'the email address in the place of user name') % email_address ) return None else: if login_providers[provider_name]['check_password'](username, password): try: #if have user associated with this username and provider, #return the user assoc = UserAssociation.objects.get( openid_url = username + '@' + provider_name,#a hack - par name is bad provider_name = provider_name ) return assoc.user except UserAssociation.DoesNotExist: #race condition here a user with this name may exist user, created = User.objects.get_or_create(username = username) if created: user.set_password(password) user.save() user_registered.send(None, user = user) else: #have username collision - so make up a more unique user name #bug: - if user already exists with the new username - we are in trouble new_username = '******' % (username, provider_name) user = User.objects.create_user(new_username, '', password) user_registered.send(None, user = user) message = _( 'Welcome! Please set email address (important!) in your ' 'profile and adjust screen name, if necessary.' ) user.message_set.create(message = message) else: return None #this is a catch - make login token a little more unique #for the cases when passwords are the same for two users #from the same provider try: assoc = UserAssociation.objects.get( user = user, provider_name = provider_name ) except UserAssociation.DoesNotExist: assoc = UserAssociation( user = user, provider_name = provider_name ) assoc.openid_url = username + '@' + provider_name#has to be this way for external pw logins elif method == 'openid': provider_name = util.get_provider_name(openid_url) try: assoc = UserAssociation.objects.get( openid_url = openid_url, provider_name = provider_name ) user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'email': #with this method we do no use user association try: #todo: add email_key_timestamp field #and check key age user = User.objects.get(email_key = email_key) user.email_key = None #one time key so delete it user.email_isvalid = True user.save() return user except User.DoesNotExist: return None elif method == 'oauth': if login_providers[provider_name]['type'] == 'oauth': try: assoc = UserAssociation.objects.get( openid_url = oauth_user_id, provider_name = provider_name ) user = assoc.user except UserAssociation.DoesNotExist: return None else: return None elif method == 'facebook': try: #assert(provider_name == 'facebook') assoc = UserAssociation.objects.get( openid_url = facebook_user_id, provider_name = 'facebook' ) user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'ldap': user = ldap_authenticate(username, password) elif method == 'wordpress_site': try: custom_wp_openid_url = '%s?user_id=%s' % (wordpress_url, wp_user_id) assoc = UserAssociation.objects.get( openid_url = custom_wp_openid_url, provider_name = 'wordpress_site' ) user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'force': return self.get_user(user_id) else: raise TypeError('only openid and password supported') if assoc: #update last used time assoc.last_used_timestamp = datetime.datetime.now() assoc.save() return user
def signup_with_password(request): """Create a password-protected account template: authopenid/signup_with_password.html """ logging.debug(get_request_info(request)) next = get_next_url(request) login_form = forms.LoginForm(initial={'next': next}) #this is safe because second decorator cleans this field provider_name = request.REQUEST['login_provider'] if askbot_settings.USE_RECAPTCHA: RegisterForm = forms.SafeClassicRegisterForm else: RegisterForm = forms.ClassicRegisterForm logging.debug('request method was %s' % request.method) if request.method == 'POST': form = RegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) #validation outside if to remember form values logging.debug('validating classic register form') form1_is_valid = form.is_valid() if form1_is_valid: logging.debug('classic register form validated') else: logging.debug('classic register form is not valid') form2_is_valid = email_feeds_form.is_valid() if form2_is_valid: logging.debug('email feeds form validated') else: logging.debug('email feeds form is not valid') if form1_is_valid and form2_is_valid: logging.debug('both forms are valid') next = form.cleaned_data['next'] username = form.cleaned_data['username'] password = form.cleaned_data['password1'] email = form.cleaned_data['email'] provider_name = form.cleaned_data['login_provider'] new_user = User.objects.create_user(username, email, password) user_registered.send(None, user=new_user) logging.debug('new user %s created' % username) if provider_name != 'local': raise NotImplementedError('must run create external user code') user = authenticate(username=username, password=password, provider_name=provider_name, method='password') login(request, user) logging.debug('new user logged in') email_feeds_form.save(user) logging.debug('email feeds form saved') # send email #subject = _("Welcome email subject line") #message_template = get_emplate( # 'authopenid/confirm_email.txt' #) #message_context = Context({ # 'signup_url': askbot_settings.APP_URL + reverse('user_signin'), # 'username': username, # 'password': password, #}) #message = message_template.render(message_context) #send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, # [user.email]) #logging.debug('new password acct created, confirmation email sent!') return HttpResponseRedirect(next) else: #todo: this can be solved with a decorator, maybe form.initial['login_provider'] = provider_name logging.debug('create classic account forms were invalid') else: #todo: here we have duplication of get_password_login_provider... form = RegisterForm(initial={ 'next': next, 'login_provider': provider_name }) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() logging.debug('printing legacy signup form') major_login_providers = util.get_enabled_major_login_providers() minor_login_providers = util.get_enabled_minor_login_providers() context_data = { 'form': form, 'page_class': 'openid-signin', 'email_feeds_form': email_feeds_form, 'major_login_providers': major_login_providers.values(), 'minor_login_providers': minor_login_providers.values(), 'login_form': login_form } return render_into_skin('authopenid/signup_with_password.html', context_data, request)
def register(request, login_provider_name=None, user_identifier=None): """ this function is used via it's own url with request.method=POST or as a simple function call from "finalize_generic_signin" in which case request.method must ge 'GET' and login_provider_name and user_identifier arguments must not be None this function may need to be refactored to simplify the usage pattern template : authopenid/complete.html """ logging.debug('') next_url = get_next_url(request) user = None is_redirect = False username = request.session.get('username', '') email = request.session.get('email', '') logging.debug('request method is %s' % request.method) register_form = forms.OpenidRegisterForm( initial={ 'next': next_url, 'username': request.session.get('username', ''), 'email': request.session.get('email', ''), }) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() if request.method == 'GET': assert (login_provider_name is not None) assert (user_identifier is not None) #store this data into the session #to persist for the post request request.session['login_provider_name'] = login_provider_name request.session['user_identifier'] = user_identifier elif request.method == 'POST': if 'login_provider_name' not in request.session \ or 'user_identifier' not in request.session: logging.critical('illegal attempt to register') return HttpResponseRedirect(reverse('user_signin')) #load this data from the session user_identifier = request.session['user_identifier'] login_provider_name = request.session['login_provider_name'] logging.debug('trying to create new account associated with openid') register_form = forms.OpenidRegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) if not register_form.is_valid(): logging.debug('OpenidRegisterForm is INVALID') elif not email_feeds_form.is_valid(): logging.debug('SimpleEmailSubscribeForm is INVALID') else: logging.debug( 'OpenidRegisterForm and SimpleEmailSubscribeForm are valid') is_redirect = True username = register_form.cleaned_data['username'] email = register_form.cleaned_data['email'] user = User.objects.create_user(username, email) user_registered.send(None, user=user) logging.debug('creating new openid user association for %s') UserAssociation( openid_url=user_identifier, user=user, provider_name=login_provider_name, last_used_timestamp=datetime.datetime.now()).save() del request.session['user_identifier'] del request.session['login_provider_name'] logging.debug('logging the user in') user = authenticate(method='force', user_id=user.id) if user is None: error_message = 'please make sure that ' + \ 'askbot.deps.django_authopenid.backends.AuthBackend' + \ 'is in your settings.AUTHENTICATION_BACKENDS' raise Exception(error_message) login(request, user) logging.debug('saving email feed settings') email_feeds_form.save(user) #check if we need to post a question that was added anonymously #this needs to be a function call becase this is also done #if user just logged in and did not need to create the new account if user != None: if askbot_settings.EMAIL_VALIDATION == True: logging.debug('sending email validation') send_new_email_key(user, nomessage=True) output = validation_email_sent(request) set_email_validation_message( user) #message set after generating view return output if user.is_authenticated(): logging.debug('success, send user to main page') return HttpResponseRedirect(reverse('index')) else: logging.debug('have really strange error') raise Exception( 'openid login failed') #should not ever get here providers = { 'yahoo': '<font color="purple">Yahoo!</font>', 'flickr': '<font color="#0063dc">flick</font><font color="#ff0084">r</font>™', 'google': 'Google™', 'aol': '<font color="#31658e">AOL</font>', 'myopenid': 'MyOpenID', } if login_provider_name not in providers: provider_logo = login_provider_name logging.error( 'openid provider named "%s" has no pretty customized logo' % login_provider_name) else: provider_logo = providers[login_provider_name] logging.debug('printing authopenid/complete.html output') data = { 'openid_register_form': register_form, 'email_feeds_form': email_feeds_form, 'provider': mark_safe(provider_logo), 'username': username, 'email': email, 'login_type': 'openid', 'gravatar_faq_url': reverse('faq') + '#gravatar', } return render_into_skin('authopenid/complete.html', data, request)
def ldap_authenticate(username, password): """ Authenticate using ldap python-ldap must be installed http://pypi.python.org/pypi/python-ldap/2.4.6 """ import ldap user_information = None try: ldap_check = ldap.initialize(askbot_settings.LDAP_URL) ldap_check.protocol_version = ldap.VERSION3 if askbot_settings.USE_LDAP_BOT: ldap_check.bind_s(askbot_settings.LDAP_BOT_USERNAME, askbot_settings.LDAP_BOT_PASSWORD) user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD, username) res = ldap_check.search_s(askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, None) if askbot_settings.USE_LDAP_BOT: ldap_check.unbind_s() if res: # User found in LDAP Directory user_dn = res[0][0] user_information = res[0][1] ldap_session = ldap.initialize(askbot_settings.LDAP_URL) ldap_session.protocol_version = ldap.VERSION3 try: ldap_session.simple_bind_s(user_dn, password) ldap_session.unbind_s() exact_username = user_information[askbot_settings.LDAP_USERID_FIELD][0] first_name = user_information[askbot_settings.LDAP_FNAME_FIELD][0] last_name = user_information[askbot_settings.LDAP_SNAME_FIELD][0] real_name = user_information[askbot_settings.LDAP_COMMONNAME_FIELD][0] email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0] try: user = User.objects.get(username__exact=exact_username) # always update user profile to synchronize with ldap server user.set_password(password) user.first_name = first_name user.last_name = last_name user.real_name = real_name user.email = email user.is_staff = False user.is_superuser = False user.save() except User.DoesNotExist: # create a new local user user = User() user.username = exact_username user.set_password(password) user.first_name = first_name user.last_name = last_name user.real_name = real_name user.email = email user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user = user) log.info('Created New User : [{0}]'.format(exact_username)) return user except ldap.INVALID_CREDENTIALS: return None else: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None except Exception, e: log.error("Unexpected Exception Occurred") log.exception(e) raise e return None
def authenticate( self, username=None, #for 'password' and 'ldap' password=None, #for 'password' and 'ldap' user_id=None, #for 'force' provider_name=None, #required with all except email_key openid_url=None, email_key=None, oauth_user_id=None, #used with oauth facebook_user_id=None, #user with facebook wordpress_url=None, # required for self hosted wordpress wp_user_id=None, # required for self hosted wordpress method=None, #requried parameter ): """this authentication function supports many login methods just which method it is going to use it determined from the signature of the function call """ login_providers = util.get_enabled_login_providers() assoc = None # UserAssociation not needed for ldap if method == 'password': if login_providers[provider_name]['type'] != 'password': raise ImproperlyConfigured('login provider must use password') if provider_name == 'local': try: user = User.objects.get(username=username) if not user.check_password(password): return None except User.DoesNotExist: try: email_address = username user = User.objects.get(email=email_address) if not user.check_password(password): return None except User.DoesNotExist: return None except User.MultipleObjectsReturned: LOG.critical( ('have more than one user with email %s ' + 'he/she will not be able to authenticate with ' + 'the email address in the place of user name') % email_address) return None else: if login_providers[provider_name]['check_password'](username, password): try: #if have user associated with this username and provider, #return the user assoc = UserAssociation.objects.get( openid_url=username + '@' + provider_name, #a hack - par name is bad provider_name=provider_name) return assoc.user except UserAssociation.DoesNotExist: #race condition here a user with this name may exist user, created = User.objects.get_or_create( username=username) if created: user.set_password(password) user.save() user_registered.send(None, user=user) else: #have username collision - so make up a more unique user name #bug: - if user already exists with the new username - we are in trouble new_username = '******' % (username, provider_name) user = User.objects.create_user( new_username, '', password) user_registered.send(None, user=user) message = _( 'Welcome! Please set email address (important!) in your ' 'profile and adjust screen name, if necessary.' ) user.message_set.create(message=message) else: return None #this is a catch - make login token a little more unique #for the cases when passwords are the same for two users #from the same provider try: assoc = UserAssociation.objects.get( user=user, provider_name=provider_name) except UserAssociation.DoesNotExist: assoc = UserAssociation(user=user, provider_name=provider_name) assoc.openid_url = username + '@' + provider_name #has to be this way for external pw logins elif method == 'openid': try: assoc = UserAssociation.objects.get(openid_url=openid_url) user = assoc.user except UserAssociation.DoesNotExist: return None except UserAssociation.MultipleObjectsReturned: logging.critical('duplicate openid url in the database!!! %s' % openid_url) return None elif method == 'email': #with this method we do no use user association try: #todo: add email_key_timestamp field #and check key age user = User.objects.get(email_key=email_key) user.email_key = None #one time key so delete it user.email_isvalid = True user.save() return user except User.DoesNotExist: return None elif method == 'oauth': if login_providers[provider_name]['type'] in ('oauth', 'oauth2'): try: assoc = UserAssociation.objects.get( openid_url=oauth_user_id, provider_name=provider_name) user = assoc.user except UserAssociation.DoesNotExist: return None else: return None elif method == 'facebook': try: #assert(provider_name == 'facebook') assoc = UserAssociation.objects.get( openid_url=facebook_user_id, provider_name='facebook') user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'ldap': user_info = ldap_authenticate(username, password) if user_info['success'] == False: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None else: #load user by association or maybe auto-create one ldap_username = user_info['ldap_username'] try: #todo: provider_name is hardcoded - possible conflict assoc = UserAssociation.objects.get( openid_url=ldap_username + '@ldap', provider_name='ldap') user = assoc.user except UserAssociation.DoesNotExist: #email address is required if 'email' in user_info and askbot_settings.LDAP_AUTOCREATE_USERS: assoc = ldap_create_user(user_info) user = assoc.user else: return None elif method == 'wordpress_site': try: custom_wp_openid_url = '%s?user_id=%s' % (wordpress_url, wp_user_id) assoc = UserAssociation.objects.get( openid_url=custom_wp_openid_url, provider_name='wordpress_site') user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'force': return self.get_user(user_id) else: raise TypeError('only openid and password supported') if assoc: #update last used time assoc.last_used_timestamp = datetime.datetime.now() assoc.save() return user
def signup_with_password(request): """Create a password-protected account template: authopenid/signup_with_password.html """ logging.debug(get_request_info(request)) next = get_next_url(request) login_form = forms.LoginForm(initial = {'next': next}) #this is safe because second decorator cleans this field provider_name = request.REQUEST['login_provider'] if askbot_settings.USE_RECAPTCHA: RegisterForm = forms.SafeClassicRegisterForm else: RegisterForm = forms.ClassicRegisterForm logging.debug('request method was %s' % request.method) if request.method == 'POST': form = RegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) #validation outside if to remember form values logging.debug('validating classic register form') form1_is_valid = form.is_valid() if form1_is_valid: logging.debug('classic register form validated') else: logging.debug('classic register form is not valid') form2_is_valid = email_feeds_form.is_valid() if form2_is_valid: logging.debug('email feeds form validated') else: logging.debug('email feeds form is not valid') if form1_is_valid and form2_is_valid: logging.debug('both forms are valid') next = form.cleaned_data['next'] username = form.cleaned_data['username'] password = form.cleaned_data['password1'] email = form.cleaned_data['email'] provider_name = form.cleaned_data['login_provider'] new_user = User.objects.create_user(username, email, password) user_registered.send(None, user = new_user) logging.debug('new user %s created' % username) if provider_name != 'local': raise NotImplementedError('must run create external user code') user = authenticate( username = username, password = password, provider_name = provider_name, method = 'password' ) login(request, user) logging.debug('new user logged in') email_feeds_form.save(user) logging.debug('email feeds form saved') # send email #subject = _("Welcome email subject line") #message_template = get_emplate( # 'authopenid/confirm_email.txt' #) #message_context = Context({ # 'signup_url': askbot_settings.APP_URL + reverse('user_signin'), # 'username': username, # 'password': password, #}) #message = message_template.render(message_context) #send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, # [user.email]) #logging.debug('new password acct created, confirmation email sent!') return HttpResponseRedirect(next) else: #todo: this can be solved with a decorator, maybe form.initial['login_provider'] = provider_name logging.debug('create classic account forms were invalid') else: #todo: here we have duplication of get_password_login_provider... form = RegisterForm( initial={ 'next':next, 'login_provider': provider_name } ) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() logging.debug('printing legacy signup form') major_login_providers = util.get_enabled_major_login_providers() minor_login_providers = util.get_enabled_minor_login_providers() context_data = { 'form': form, 'page_class': 'openid-signin', 'email_feeds_form': email_feeds_form, 'major_login_providers': major_login_providers.values(), 'minor_login_providers': minor_login_providers.values(), 'login_form': login_form } return render_into_skin( 'authopenid/signup_with_password.html', context_data, request )
def register(request, login_provider_name=None, user_identifier=None): """ this function is used via it's own url with request.method=POST or as a simple function call from "finalize_generic_signin" in which case request.method must ge 'GET' and login_provider_name and user_identifier arguments must not be None this function may need to be refactored to simplify the usage pattern template : authopenid/complete.html """ logging.debug('') next_url = get_next_url(request) user = None is_redirect = False username = request.session.get('username', '') email = request.session.get('email', '') logging.debug('request method is %s' % request.method) register_form = forms.OpenidRegisterForm( initial={ 'next': next_url, 'username': request.session.get('username', ''), 'email': request.session.get('email', ''), } ) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm() if request.method == 'GET': assert(login_provider_name is not None) assert(user_identifier is not None) #store this data into the session #to persist for the post request request.session['login_provider_name'] = login_provider_name request.session['user_identifier'] = user_identifier elif request.method == 'POST': if 'login_provider_name' not in request.session \ or 'user_identifier' not in request.session: logging.critical('illegal attempt to register') return HttpResponseRedirect(reverse('user_signin')) #load this data from the session user_identifier = request.session['user_identifier'] login_provider_name = request.session['login_provider_name'] logging.debug('trying to create new account associated with openid') register_form = forms.OpenidRegisterForm(request.POST) email_feeds_form = askbot_forms.SimpleEmailSubscribeForm(request.POST) if not register_form.is_valid(): logging.debug('OpenidRegisterForm is INVALID') elif not email_feeds_form.is_valid(): logging.debug('SimpleEmailSubscribeForm is INVALID') else: logging.debug('OpenidRegisterForm and SimpleEmailSubscribeForm are valid') is_redirect = True username = register_form.cleaned_data['username'] email = register_form.cleaned_data['email'] user = User.objects.create_user(username, email) user_registered.send(None, user = user) logging.debug('creating new openid user association for %s') UserAssociation( openid_url = user_identifier, user = user, provider_name = login_provider_name, last_used_timestamp = datetime.datetime.now() ).save() del request.session['user_identifier'] del request.session['login_provider_name'] logging.debug('logging the user in') user = authenticate(method = 'force', user_id = user.id) if user is None: error_message = 'please make sure that ' + \ 'askbot.deps.django_authopenid.backends.AuthBackend' + \ 'is in your settings.AUTHENTICATION_BACKENDS' raise Exception(error_message) login(request, user) logging.debug('saving email feed settings') email_feeds_form.save(user) #check if we need to post a question that was added anonymously #this needs to be a function call becase this is also done #if user just logged in and did not need to create the new account if user != None: if askbot_settings.EMAIL_VALIDATION == True: logging.debug('sending email validation') send_new_email_key(user, nomessage=True) output = validation_email_sent(request) set_email_validation_message(user) #message set after generating view return output if user.is_authenticated(): logging.debug('success, send user to main page') return HttpResponseRedirect(reverse('index')) else: logging.debug('have really strange error') raise Exception('openid login failed')#should not ever get here providers = { 'yahoo':'<font color="purple">Yahoo!</font>', 'flickr':'<font color="#0063dc">flick</font><font color="#ff0084">r</font>™', 'google':'Google™', 'aol':'<font color="#31658e">AOL</font>', 'myopenid':'MyOpenID', } if login_provider_name not in providers: provider_logo = login_provider_name logging.error('openid provider named "%s" has no pretty customized logo' % login_provider_name) else: provider_logo = providers[login_provider_name] logging.debug('printing authopenid/complete.html output') data = { 'openid_register_form': register_form, 'email_feeds_form': email_feeds_form, 'provider':mark_safe(provider_logo), 'username': username, 'email': email, 'login_type':'openid', 'gravatar_faq_url':reverse('faq') + '#gravatar', } return render_into_skin('authopenid/complete.html', data, request)
def authenticate( self, username = None,#for 'password' and 'ldap' password = None,#for 'password' and 'ldap' user_id = None,#for 'force' provider_name = None,#required with all except email_key openid_url = None, email_key = None, oauth_user_id = None,#used with oauth facebook_user_id = None,#user with facebook wordpress_url = None, # required for self hosted wordpress wp_user_id = None, # required for self hosted wordpress cas_ticket = None, # the CAS ticket method = None,#requried parameter ): """this authentication function supports many login methods just which method it is going to use it determined from the signature of the function call """ login_providers = util.get_enabled_login_providers() assoc = None # UserAssociation not needed for ldap if method == 'password': if login_providers[provider_name]['type'] != 'password': raise ImproperlyConfigured('login provider must use password') if provider_name == 'local': try: user = User.objects.get(username=username) if not user.check_password(password): return None except User.DoesNotExist: try: email_address = username user = User.objects.get(email = email_address) if not user.check_password(password): return None except User.DoesNotExist: return None except User.MultipleObjectsReturned: LOG.critical( ('have more than one user with email %s ' + 'he/she will not be able to authenticate with ' + 'the email address in the place of user name') % email_address ) return None else: if login_providers[provider_name]['check_password'](username, password): try: #if have user associated with this username and provider, #return the user assoc = UserAssociation.objects.get( openid_url = username + '@' + provider_name,#a hack - par name is bad provider_name = provider_name ) return assoc.user except UserAssociation.DoesNotExist: #race condition here a user with this name may exist user, created = User.objects.get_or_create(username = username) if created: user.set_password(password) user.save() user_registered.send(None, user = user) else: #have username collision - so make up a more unique user name #bug: - if user already exists with the new username - we are in trouble new_username = '******' % (username, provider_name) user = User.objects.create_user(new_username, '', password) user_registered.send(None, user = user) message = _( 'Welcome! Please set email address (important!) in your ' 'profile and adjust screen name, if necessary.' ) user.message_set.create(message = message) else: return None #this is a catch - make login token a little more unique #for the cases when passwords are the same for two users #from the same provider try: assoc = UserAssociation.objects.get( user = user, provider_name = provider_name ) except UserAssociation.DoesNotExist: assoc = UserAssociation( user = user, provider_name = provider_name ) assoc.openid_url = username + '@' + provider_name#has to be this way for external pw logins elif method == 'openid': try: assoc = UserAssociation.objects.get(openid_url=openid_url) user = assoc.user except UserAssociation.DoesNotExist: return None except UserAssociation.MultipleObjectsReturned: logging.critical( 'duplicate openid url in the database!!! %s' % openid_url ) return None elif method == 'email': #with this method we do no use user association try: #todo: add email_key_timestamp field #and check key age user = User.objects.get(email_key = email_key) user.email_key = None #one time key so delete it user.email_isvalid = True user.save() return user except User.DoesNotExist: return None elif method == 'oauth': if login_providers[provider_name]['type'] == 'oauth': try: assoc = UserAssociation.objects.get( openid_url = oauth_user_id, provider_name = provider_name ) user = assoc.user except UserAssociation.DoesNotExist: return None else: return None elif method == 'facebook': try: #assert(provider_name == 'facebook') assoc = UserAssociation.objects.get( openid_url = facebook_user_id, provider_name = 'facebook' ) user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'ldap': user_info = ldap_authenticate(username, password) if user_info['success'] == False: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None else: #load user by association or maybe auto-create one ldap_username = user_info['ldap_username'] try: #todo: provider_name is hardcoded - possible conflict assoc = UserAssociation.objects.get( openid_url = ldap_username + '@ldap', provider_name = 'ldap' ) user = assoc.user except UserAssociation.DoesNotExist: #email address is required if 'email' in user_info and askbot_settings.LDAP_AUTOCREATE_USERS: assoc = ldap_create_user(user_info) user = assoc.user else: return None elif method == 'cas': import caslib cas_response = caslib.cas_serviceValidate(cas_ticket) success, _user = cas_response.map[cas_response.type].get('user',None) if success: try: assoc = UserAssociation.objects.get( openid_url = _user + '@ldap', provider_name = 'ldap' ) user = assoc.user except UserAssociation.DoesNotExist: user = User() user.username = _user user.set_unusable_password() user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user = user) LOG.info('Created New User : [{0}]'.format(_user)) assoc = UserAssociation() assoc.user = _user assoc.openid_url = _user + '@ldap' assoc.provider_name = 'ldap' assoc.save() else: return None elif method == 'wordpress_site': try: custom_wp_openid_url = '%s?user_id=%s' % (wordpress_url, wp_user_id) assoc = UserAssociation.objects.get( openid_url = custom_wp_openid_url, provider_name = 'wordpress_site' ) user = assoc.user except UserAssociation.DoesNotExist: return None elif method == 'force': return self.get_user(user_id) else: raise TypeError('only openid and password supported') if assoc: #update last used time assoc.last_used_timestamp = datetime.datetime.now() assoc.save() return user
def authenticate( self, username=None, # for 'password' and 'ldap' password=None, # for 'password' and 'ldap' user_id=None, # for 'force' provider_name=None, # required with all except email_key openid_url=None, email_key=None, oauth_user_id=None, # used with oauth facebook_user_id=None, # user with facebook wordpress_url=None, # required for self hosted wordpress wp_user_id=None, # required for self hosted wordpress method=None, # requried parameter ): """this authentication function supports many login methods just which method it is going to use it determined from the signature of the function call """ login_providers = util.get_enabled_login_providers() assoc = None # UserAssociation not needed for ldap if method == "password": if login_providers[provider_name]["type"] != "password": raise ImproperlyConfigured("login provider must use password") if provider_name == "local": try: user = User.objects.get(username=username) if not user.check_password(password): return None except User.DoesNotExist: try: email_address = username user = User.objects.get(email=email_address) if not user.check_password(password): return None except User.DoesNotExist: return None except User.MultipleObjectsReturned: LOG.critical( ( "have more than one user with email %s " + "he/she will not be able to authenticate with " + "the email address in the place of user name" ) % email_address ) return None else: if login_providers[provider_name]["check_password"](username, password): try: # if have user associated with this username and provider, # return the user assoc = UserAssociation.objects.get( openid_url=username + "@" + provider_name, # a hack - par name is bad provider_name=provider_name, ) return assoc.user except UserAssociation.DoesNotExist: # race condition here a user with this name may exist user, created = User.objects.get_or_create(username=username) if created: user.set_password(password) user.save() user_registered.send(None, user=user) else: # have username collision - so make up a more unique user name # bug: - if user already exists with the new username - we are in trouble new_username = "******" % (username, provider_name) user = User.objects.create_user(new_username, "", password) user_registered.send(None, user=user) message = _( "Welcome! Please set email address (important!) in your " "profile and adjust screen name, if necessary." ) user.message_set.create(message=message) else: return None # this is a catch - make login token a little more unique # for the cases when passwords are the same for two users # from the same provider try: assoc = UserAssociation.objects.get(user=user, provider_name=provider_name) except UserAssociation.DoesNotExist: assoc = UserAssociation(user=user, provider_name=provider_name) assoc.openid_url = username + "@" + provider_name # has to be this way for external pw logins elif method == "openid": try: assoc = UserAssociation.objects.get(openid_url=openid_url) user = assoc.user except UserAssociation.DoesNotExist: return None except UserAssociation.MultipleObjectsReturned: logging.critical("duplicate openid url in the database!!! %s" % openid_url) return None elif method == "email": # with this method we do no use user association try: # todo: add email_key_timestamp field # and check key age user = User.objects.get(email_key=email_key) user.email_key = None # one time key so delete it user.email_isvalid = True user.save() return user except User.DoesNotExist: return None elif method == "oauth": if login_providers[provider_name]["type"] in ("oauth", "oauth2"): try: assoc = UserAssociation.objects.get(openid_url=oauth_user_id, provider_name=provider_name) user = assoc.user except UserAssociation.DoesNotExist: return None else: return None elif method == "facebook": try: # assert(provider_name == 'facebook') assoc = UserAssociation.objects.get(openid_url=facebook_user_id, provider_name="facebook") user = assoc.user except UserAssociation.DoesNotExist: return None elif method == "ldap": # user_info = ldap_authenticate(username, password) user_info = util.ldap_check_password(username, password) if user_info["success"] == False: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None else: # load user by association or maybe auto-create one ldap_username = user_info["ldap_username"] try: # todo: provider_name is hardcoded - possible conflict assoc = UserAssociation.objects.get(openid_url=ldap_username, provider_name="Wind River LDAP") user = assoc.user except UserAssociation.DoesNotExist: # email address is required if "email" in user_info and askbot_settings.LDAP_AUTOCREATE_USERS: assoc = ldap_create_user(user_info) user = assoc.user else: return None elif method == "wordpress_site": try: custom_wp_openid_url = "%s?user_id=%s" % (wordpress_url, wp_user_id) assoc = UserAssociation.objects.get(openid_url=custom_wp_openid_url, provider_name="wordpress_site") user = assoc.user except UserAssociation.DoesNotExist: return None elif method == "force": return self.get_user(user_id) else: raise TypeError("only openid and password supported") if assoc: # update last used time assoc.last_used_timestamp = datetime.datetime.now() assoc.save() return user
def ldap_authenticate(username, password): """ Authenticate using ldap python-ldap must be installed http://pypi.python.org/pypi/python-ldap/2.4.6 """ import ldap user_information = None try: ldap_session = ldap.initialize(askbot_settings.LDAP_URL) #set protocol version if askbot_settings.LDAP_PROTOCOL_VERSION == '2': ldap_session.protocol_version = ldap.VERSION2 elif askbot_settings.LDAP_PROTOCOL_VERSION == '3': ldap_session.protocol_version = ldap.VERSION3 else: raise NotImplementedError('unsupported version of ldap protocol') ldap.set_option(ldap.OPT_REFERRALS, 0) #set extra ldap options, if given if hasattr(django_settings, 'LDAP_EXTRA_OPTIONS'): options = django_settings.LDAP_EXTRA_OPTIONS for key, value in options: if key.startswith('OPT_'): ldap_key = getattr(ldap, key) ldap.set_option(ldap_key, value) else: raise ValueError('Invalid LDAP option %s' % key) #add optional "master" LDAP authentication, if required master_username = getattr(django_settings, 'LDAP_USER', None) master_password = getattr(django_settings, 'LDAP_PASSWORD', None) login_name_field = askbot_settings.LDAP_LOGIN_NAME_FIELD base_dn = askbot_settings.LDAP_BASE_DN login_template = login_name_field + '=%s,' + base_dn encoding = askbot_settings.LDAP_ENCODING if master_username and master_password: login_dn = login_template % master_username ldap_session.simple_bind_s( login_dn.encode(encoding), master_password.encode(encoding) ) user_filter = askbot_settings.LDAP_USER_FILTER_TEMPLATE % ( askbot_settings.LDAP_LOGIN_NAME_FIELD, username ) email_field = askbot_settings.LDAP_EMAIL_FIELD get_attrs = [ email_field.encode(encoding), login_name_field.encode(encoding) #str(askbot_settings.LDAP_USERID_FIELD) #todo: here we have a chance to get more data from LDAP #maybe a point for some plugin ] common_name_field = askbot_settings.LDAP_COMMON_NAME_FIELD.strip() given_name_field = askbot_settings.LDAP_GIVEN_NAME_FIELD.strip() surname_field = askbot_settings.LDAP_SURNAME_FIELD.strip() if given_name_field and surname_field: get_attrs.append(given_name_field.encode(encoding)) get_attrs.append(surname_field.encode(encoding)) elif common_name_field: get_attrs.append(common_name_field.encode(encoding)) # search ldap directory for user user_search_result = ldap_session.search_s( askbot_settings.LDAP_BASE_DN.encode(encoding), ldap.SCOPE_SUBTREE, user_filter.encode(encoding), get_attrs ) if user_search_result: # User found in LDAP Directory user_dn = user_search_result[0][0] user_information = user_search_result[0][1] ldap_session.simple_bind_s(user_dn, password.encode(encoding)) #raises INVALID_CREDENTIALS ldap_session.unbind_s() exact_username = user_information[login_name_field][0] email = user_information[email_field][0] if given_name_field and surname_field: last_name = user_information[surname_field][0] first_name = user_information[given_name_field][0] elif surname_field: common_name_format = askbot_settings.LDAP_COMMON_NAME_FIELD_FORMAT common_name = user_information[common_name_field][0] first_name, last_name = split_name(common_name, common_name_format) #here we have an opportunity to copy password in the auth_user table #but we don't do it for security reasons try: user = User.objects.get(username__exact=exact_username) # always update user profile to synchronize with ldap server user.set_unusable_password() #user.first_name = first_name #user.last_name = last_name user.email = email user.save() except User.DoesNotExist: # create new user in local db user = User() user.username = exact_username user.set_unusable_password() #user.first_name = first_name #user.last_name = last_name user.email = email user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user = user) log.info('Created New User : [{0}]'.format(exact_username)) return user else: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None except ldap.INVALID_CREDENTIALS, e: return None # Will fail login on return of None
def ldap_authenticate(username, password): """ Authenticate using ldap python-ldap must be installed http://pypi.python.org/pypi/python-ldap/2.4.6 """ import ldap user_information = None try: ldap_session = ldap.initialize(askbot_settings.LDAP_URL) ldap_session.protocol_version = ldap.VERSION3 user_filter = "({0}={1})".format(askbot_settings.LDAP_USERID_FIELD, username) # search ldap directory for user res = ldap_session.search_s(askbot_settings.LDAP_BASEDN, ldap.SCOPE_SUBTREE, user_filter, None) if res: # User found in LDAP Directory user_dn = res[0][0] user_information = res[0][1] ldap_session.simple_bind_s( user_dn, password) # <-- will throw ldap.INVALID_CREDENTIALS if fails ldap_session.unbind_s() exact_username = user_information[ askbot_settings.LDAP_USERID_FIELD][0] # Assuming last, first order # --> may be different last_name, first_name = user_information[ askbot_settings.LDAP_COMMONNAME_FIELD][0].rsplit(" ", 1) email = user_information[askbot_settings.LDAP_EMAIL_FIELD][0] try: user = User.objects.get(username__exact=exact_username) # always update user profile to synchronize with ldap server user.set_password(password) user.first_name = first_name user.last_name = last_name user.email = email user.save() except User.DoesNotExist: # create new user in local db user = User() user.username = exact_username user.set_password(password) user.first_name = first_name user.last_name = last_name user.email = email user.is_staff = False user.is_superuser = False user.is_active = True user.save() user_registered.send(None, user=user) log.info('Created New User : [{0}]'.format(exact_username)) return user else: # Maybe a user created internally (django admin user) try: user = User.objects.get(username__exact=username) if user.check_password(password): return user else: return None except User.DoesNotExist: return None except ldap.INVALID_CREDENTIALS, e: return None # Will fail login on return of None