How to crypt mine password in postgreSQL? - postgresql

Trying to crypt mine function and get it back,need your help tell me please what i am doing wrong ?
SELECT user_id
FROM users
WHERE email = 'Natali#gmail.com' AND u_password = crypt(u_password, '#kjvfhjh88976');
// Null result
INSERT INTO users (user_id, nick_name, email, u_password)
VALUES
(87678655, 'Natali1990#', 'Natali#gmail.com', crypt('#kjvfhjh88976', gen_salt('bf')));
SELECT user_id FROM users WHERE email = 'Natali#gmail.com'; // Working

You are using the pgcrypto package incorrectly, and given that it is confusing, this is not a surprise. Your current insert seems fine:
INSERT INTO users (user_id, nick_name, email, u_password)
VALUES
(87678655, 'Natali1990#', 'Natali#gmail.com',
CRYPT('#kjvfhjh88976', GEN_SALT('bf')));
Then, to authenticate a user, use a SELECT looking something like the following:
SELECT u_password = CRYPT('#kjvfhjh88976', u_password)
FROM users
WHERE email = 'Natali#gmail.com';
This would return true if the user entered the correct password. You may read more about this in the Postgres documentation;

Related

supabase auth.uid() = user_id equals false

I have a very strange problem that is driving we up the walls.
I am creating the following table
CREATE TABLE articles(
id BIGINT generated by default as IDENTITY PRIMARY KEY,
user_id uuid references auth.users NOT NULL,
title TEXT,
CONTENT TEXT,
user_email TEXT,
inserted_at TIMESTAMP WITH TIME ZONE DEFAULT timezone('utc'::TEXT,NOW()) NOT NULL
);
ALTER TABLE articles ENABLE ROW LEVEL SECURITY;
CREATE policy "users can create articles" ON articles for
INSERT WITH CHECK(auth.uid() = user_id);
CREATE policy "users can update their own articles" ON articles for
UPDATE USING (auth.uid() = user_id);
CREATE policy "users can delete their own articles" ON articles for
DELETE USING (auth.uid() = user_id);
CREATE policy "users can read their own articles" ON articles for
SELECT USING (auth.uid() = user_id);
I can add data to it through my front-end with:
const { data, error } = await supabaseClient.from("articles").insert(
[{
title: title,
content: content,
user_email: user?.email?.toLowerCase(),
user_id: user?.id,
}]
).single()
and that works. I can verify on supabase that the row has indeed been added.
However, I can't access my data through the front-end since the expression:
auth.uid() = user_id seems to evaluate to false even though it is the same. If I disable Row level security or write TRUE instead everything works as intended.

Fetching id field of an entity in the SQL Transaction

I have the following schema.
Person(pid, pname)
Beer(bid, bname)
Likes(pid,bid)
I would like to insert a likes item. However, I am accepting the following format for the new users : (Pid, pname, bid, bname).
I would like to create a transaction for that to avoid conflict ( This is a highly simplified version of my real problem but the issue is the same). In my Person table, I set pid Auto-Increment(or Serial in Postgresql). Also the same goes for bid.
I have stuck in a point where I know the Person does not exist but the beer exists. So, I have to create a Person, then add an entity to Likes relation.
As far as I know, when I use the Autocommit(false) in dB, the transaction won't save until the commit. So, should I change the db design:
Change the auto-increment field to a normal integer, not null field.
In the transaction, after the autoCommit(false) has begun, read the last entry of the person
Increment it by one while creating the new person
Then create likes relation
Or, is there any other way around or do I miss something about transactions?
Here is what I have done so far:
try {
String add_person_sql = "INSERT INTO Person (name) VALUES(?)";
PreparedStatement add_person_statement = mydb.prepareStatement(add_person_sql);
String add_likes_sql = "INSERT INTO Likes (pid, bid) VALUES(?, ?)";
PreparedStatement add_likes_statement = mydb.prepareStatement(add_likes_sql);
mydb.setAutoCommit(false);
add_person_statement.setString(1, pname);
// The problem is, without saving the person I cannot know the id of the person
// AFAIK, this execution is not finished until commit occurs
add_person_statement.executeQuery();
// How can I fetch person's id
add_likes_statement.setString(1, pid);
add_likes_statement.setString(2, bid);
add_likes_statement.executeQuery();
mydb.commit();
}
catch(Exception e){
System.out.println(e);
mydb.rollback();
}
You can tell JDBC to return the generated ID from the insert statement, then you can use that ID to insert into the likes table:
mydb.prepareStatement(add_person_sql, new String[]{"pid"});
The second parameter tells the driver to return the generated value for the pid column.
Alternatively you can use
mydb.prepareStatement(add_person_sql, Statement.RETURN_GENERATED_KEYS);
that tells the driver to detect the auto increment columns.
Then run the insert using executeUpdate()
add_person_statement.setString(1, pname);
add_person_statement.executeUpdate();
int newPid = -1;
ResultSet idResult = add_person.getGeneratedKeys();
if (idResult.next()) {
newPid = idResult.getInt(1);
}
add_likes_statement.setString(1, newPid);
add_likes_statement.setString(2, bid);
add_likes_statement.executeUpdate();
mydb.commit();

Why can't I create model based results from lync but I can do anything through SqlQuery?

Any idea why this doesn't work
return View((from u in db.Users
select new Models.Users()
{
Id = u.Id,
Username = u.Username,
Password = "-"
}).ToList());
And this works like a charm? :]
return View(db.Users.SqlQuery("SELECT Id, Username, '-' AS Password FROM Users"));
Since you didn't really give a ton of information I'm gonna take a shot in the dark. EF doesn't allow you to select to a class that represents a database entity. I'm assuming the Models.Users class is the same class being used in your db.Users? You should just be able to create like a UserDto with the same fields and I think that will work. If it doesn't give more info and I'll try to help more.

SQLAlchemy + PostgreSQL quoted table name for User, with Flask-Login

Consider the following declarative User model in SQLAlchemy:
class User(Base):
id = Column(Integer, primary_key=True)
username = Column(String(50), unique=True)
email = Column(String(1024), unique=True)
points = Column(Integer, default=0)
achievements = relationship('Achievement',
secondary=achievement_association_table,
backref='users')
reviews = relationship('Review', backref='author', lazy='dynamic')
moderated = Column(Boolean, default=True)
When I do a SELECT * FROM user, I noticed that the query was not returning all of my columns, and showed only the "current_user" column which I can only surmise is a result of using Flask-Login.
Making the query User.query.all() resulted in the following SQL:
SELECT "user".created AS user_created, "user".modified AS user_modified, "user".id AS user_id, "user".username AS user_username, "user".email AS user_email, "user".points AS user_points, "user".moderated AS user_moderated
Can anyone help me understand why this table was created double quoted? None of my other (similarly defined) declarative models exhibit this behavior.
Thanks in advance!
user is a reserved words and thus needs to be quoted.
More details about quoted identifiers are in the manual:
http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

Is there a way to update a database field based on a list?

Using JPA, I have a list of entries from my database :
User(id, firstname, lastname, email)
That I get by doing:
List<User> users = User.find("lastname = ?", "smith");
And I'd like to update all in one request, by doing something like this :
"UPDATE USER SET email = null IN :list"
and then set the parameter "list" to users
Is it possible? if so, how?
Thanks for your help :)
Well, you could embed the query that you used to obtain list in the where clause of the update.
UPDATE User a SET a.email = null
WHERE user IN (SELECT b FROM User b WHERE lastName = :?)
By doing this you'd be doing the query to search the list and the update in single update query.
How do you like that? Do you think this could work?
-EDIT-
Since you want to use the original list of items instead of a list just retrieved from the database, you can still ensure you build the original list like this
UPDATE User a SET a.email = null
WHERE user IN (SELECT b FROM User b WHERE lastName IN(:originalList))
Then when you invoke it, you can do something like this:
Collection<String> originalList = Arrays.asList("Kenobi", "Skywalker", "Windu");
query.setParameter("originalList", originalList);
By this, you can still ensure the query will only contain items in your original list and not any possible new item from the database, provided that that last name is a candidate key in the database, otherwise I would recommend that you use the ID for the subquery instend of the last name.
if you have jpa+hibernate you can use entityManager.createQuery() for creating hql query
like that:
String hql = "UPDATE Supplier SET name = :newName WHERE name IN :name";
entityManager.createQuery(hql);