I'm using django-1.4.3 and the superuser can create users and assign password to them. Here I'm using django-email-as-username to enable users to login with their email as username. When the superuser adds a new user, the newly added user should be notified through email with his username and password.
I'm able to send email after user creation using post_save signal. But I couldn't get the password as it will be encrypted and stored. I want to email the user, the raw password. How can I achieve this?
I have achieved it using the code below:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
#receiver(post_save, sender = User)
def my_callback(sender, **kwargs):
import inspect
records =[]
for frame_record in inspect.stack():
records.append(frame_record[3])
if frame_record[3]=='get_response':
request = frame_record[0].f_locals['request']
email = request.POST.get('email')
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if email != None and password1 != None and password2 != None and password1 == password2:
html_content ="Hi,<br> Your username: %s <br> Password: %s"
from_email = settings.DEFAULT_FROM_EMAIL
message = EmailMessage('Welcome', html_content %(email, password1), from_email, [email])
message.content_subtype = "html" # Main content is now text/html
message.send()
break
Related
Installed crispy-forms and configured templates for authentication. Everything works well. Problem with registration. With the standard registration form, I fill out the forms, then an email is sent to the mail confirming registration with a link to activate the account. But as soon as I try to implement the crispy-forms template, the letter stops coming and immediately throws it to the login form. How do I make emails arrive using crispy-forms?
I tried a lot of things but there is no result
forms.py
your
class SignUpForm(UserCreationForm):
email = forms.EmailField(label="Email")
first_name = forms.CharField(label="Имя")
last_name = forms.CharField(label="Фамилия")
class Meta:
model = User
fields = (
"username",
"first_name",
"last_name",
"email",
"password1",
"password2",
)
text
views.py
`your
class SignUpView(CreateView):
model = User
form_class = SignUpForm
success_url = reverse_lazy('login')
template_name = 'registration/signup.html'
success_message = "Ваш профиль создан"
texturls.pyyour
urlpatterns = [
path("signup/", SignUpView.as_view(), name='signup'),
path("update/<int:pk>", AccountUserUpdate.as_view(), name='account_update'),
path('setauthor/', set_me_author, name='set_me_author'),
path('login/', views.LoginView.as_view(), name='login'),
path('logout/', views.LogoutView.as_view(), name='logout'),
path('password-change/', views.PasswordChangeView.as_view(), name='password_change'),
path('password-change/done/', views.PasswordChangeDoneView.as_view(), name='password_change_done'),
path('password-reset/', views.PasswordResetView.as_view(), name='password_reset'),
path('password-reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
text`
Consider a SQLite DB with user table having user_id, first_name, last_name, access_level columns.
After LDAP authentication, I'd like to update current_user object with additional metadata (from sql table) of the user_id.
Now, using this additional information (access_level included), user must be redirected to the view based on access permissions(access_level).
Let's say your sqlite database was called auth.db and was created like this:
$ sqlite3 auth.db
sqlite> CREATE TABLE user (user_id TEXT PRIMARY KEY, first_name TEXT, last_name TEXT, access_level TEXT);
sqlite> INSERT INTO user VALUES ('employee', 'Emp', 'Loyee', 'user');
sqlite> INSERT INTO user VALUES ('manager', 'Man', 'Ager', 'manager');
Construct your gramex.yaml like this:
url:
# Home page displays the current user object
home:
pattern: /$YAMLURL/
handler: FunctionHandler
kwargs:
function: json.dumps(handler.current_user)
# Login page uses LDAP auth
login:
pattern: /$YAMLURL/login
handler: LDAPAuth
kwargs:
# Let's connect to a test server. Login: employee. Password: Secret123
host: ipa.demo1.freeipa.org
use_ssl: true
user: 'uid={user},cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org'
password: '{password}'
# After the user logs in, send them to /login-redirect.
# This will update the current_user with additional metadata and redirect
redirect:
url: /$YAMLURL/login-redirect
# login-redirect sets the user object and redirects to relevant page
login-redirect:
pattern: /$YAMLURL/login-redirect
handler: FunctionHandler
kwargs:
function: mymodule.login_redirect(r'$YAMLPATH/auth.db', handler)
This relies on a mymodule.py which looks like this:
import sqlite3
import gramex.cache
import pandas as pd
def login_redirect(db, handler):
# The LDAP id is like uid=employee,cn=users,...
ldap_id = handler.current_user['id']
# Convert this into just the uid, which is "employee"
user_id = ldap_id.split(',')[0].split('=')[1]
# Look up the user's ID from the sqlite database
con = gramex.cache.open(db, sqlite3.connect)
result = pd.read_sql('SELECT * FROM user WHERE user_id=?', con, params=[user_id])
# Update the current user with the first entry (assuming it exists)
handler.current_user.update(result.iloc[0].to_dict())
# Redirect based on the access level
access_level = handler.current_user['access_level']
handler.redirect('.?employee-page' if access_level == 'user' else '.?invalid-page')
To try this:
Visit /login. you can log into the freeipa demo LDAP server with login employee and password Secret123
You will be redirected to /login-redirect. This looks up the user ID in auth.db, adds all other attributes into .current_user and redirects based on the access_level
How can l implement a hash function (SHA512) that encrypt the username and check if this username and password is correct in the SQL server?
Working login right now if you set a cleartext username
user = User.find_by(username: params[:session][:username].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to :root
else
flash.now[:warning] = 'Wrong username/password'
render 'new'
end
I have tried encrypt the username before it runs the if statement but I can get it to work.
The way I hash the username is:
username = params[:session][:username].downcase
username_encrypted = Digest::SHA2.new(512).hexdigest(username)
any ideas how this can be made?
What i am trying to achieve with this is. Too have one column in SQL with encrypted usernames and another column with "public" usernames. Where public usernames is visible for everybody on the site and encrypted usernames is stored in SQL only for authentication.
I am using grails 2.3.0 and facing the weird issue when encoding the password with spring security:
This is my method to encode password:
String encodePassword(String password) {
return springSecurityService.encodePassword(password)
}
and using like that
log.debug encodePassword("mkb")
log.debug encodePassword("mkb")
log.debug encodePassword("mkb")
I am encoding the same password several times and each time I am getting the different encoded password.
logs:
$2a$10$h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K
$2a$10$a7qybaiLF/eNrTSwFohjkezNaJTTDdMEinRYKjxDzEt.OoxaIgFOu
$2a$10$nZVhUT0QTmmbtt22CPtM..cLxU252RGBIMkd5aSd2AFXNTNLQ./6u
That's fine. Looks like you're using BCrypt password hash, this algorithm uses random salt each time you encode password (other hashing algorithms use a 'salt source property', like id). This salt is prepended to hash
So you have:
$2a - salt version
$10 - rounds
$h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K - Base64 for salt+hash, where salt get first 24 characters, and hash takes the rest:
h8T4BxgOeozmH/VSPJl7NeTaF - salt
2P0iONpSdqDN7dDFFAG.sy8WG/8K - hash (10 rounds for salt + password)
See Spring Security's BCrypt sources: https://github.com/spring-projects/spring-security/blob/master/crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java
If you need to check user password manually, you have to use passwordEncoder, like:
//dependency injection
def passwordEncoder
//validate
String enteredPassword = params.password
User user = ...
if (!passwordEncoder.isPasswordValid(user.password, enteredPassword, null)) { //validates raw password against hashed
//... wrong password entered
}
Grails spring security describes the process of updating a password at: https://grails-plugins.github.io/grails-spring-security-core/4.0.x/index.html
User user = User.findByUsername(username)
if (!passwordEncoder.matches(password, user.password)) {
flash.message = 'Current password is incorrect'
render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
return
}
if (passwordEncoder.matches(password_new, user.password)) {
flash.message = 'Please choose a different password from your current one'
render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
return
}
Where password or new_password are parameters or method arguments
in the callback of the authentication process I do:
auth_hash = request.env['omniauth.auth']
and then, I'm extracting the user id, but is it possible in the same time getting the user's name and email address?
You need to first get the raw data from request.env["omniauth.auth"]
data = request.env["omniauth.auth"].extra.raw_info
username = data.first_name
email = data.email
yesss
u can get it by doing
auth_hash[:info][:name] for name and auth_hash[:info][:email] for email