Redis newbie - equivalent approach to mysql table - redis

I'm new to Redis and was hoping for a "best practice" solution to implementing the equivalent of a "users" table in a mysql database, for handling users in a web app.
Would I create a users SET in Redis? Or a users database with a SET for each user?

My standard setup for users is a serialized object in a standard key u:userid - this object gets retrieved on each request, and there is never any need to access only one of the properties.
You could also use a hash rather than json for the user properties, but my setup includes everything getting used as strongly typed objects and redis running on a different server from the client, so using json makes it easier to use generic deserialization and minimizes any latency issues.
In addition to the user object itself, you will need an index for any fields you need to use to find a user - for example to allow a user to log in with email address you will need a key e:email => userid. A hash will also work here - the important thing is that you need something that is O(1) to get from an email to a user object.
Sometimes parts of the user data should have their own keys - for example a followers list is a perfect match to a redis set, so is best stored in that form.

It really depends on what you'd want to do with the Users within your application. Another option would be to have each user be it's own hash, where they keys are properties (fields) for each user (firstName, lastName, etc). You could use a key that you increment as the ID generator for inserting, and potentially another set that you use to hold all of the user IDs.

Related

Restrict access to single stream on keen

I have read access keys on keen.io And I have a use case where I would like to use these access keys. Actually, in my system, i want to make a separate stream for every customer account and want to make sure that this stream is only accessible (could be written/read) by that specific customer only. I want to use access keys for this purpose as I think it is their one of main use cases.
Can anyone tell me how can I pass this information to an access key that it is only usable on a specific stream ONLY?
You would programmatically create an Access Key for each customer and set its permissions on creation so that it will autofill event properties with, for example, a customer id. With queries, you would set up the querying permissions with a filter so that it could only query event with that customer id.
Similar to the JSON in this example here: https://keen.io/docs/access/access-keys/#access-key-json-example
Then, any time that Access Key is used, it will only be able to query that specific data and all writes will include the autofill information that you set for that Access Key.

SQL Conceptual Modelling - Can a password be a property of an entity?

I'm currently making a conceptual model for a project and one of my entities happens to be a USER. It's key is a userID, and the properties include firstName, lastName, emailAdr, and userName. A user will have a password after the project is implemented which makes me wonder if I should add it as a property... or would that jeopardize confidentiality?
Conceptually you have to keep a password for the user so it makes sense to store it in the user entity.
However, as pointed out by #stepio, when you look at how you will implement that, keeping a hash (in fact, a strong secure hash) is a good way to store it so it is not exposed if compromised.
On another side if you use an ORM that instantiates the entity from the table ,for example, and you have some concern about the hash traveling through out the application you may choose to put the real hash in a separate table, and keep a reference to it in the user's table. Something like a Unix shadow password.
Consider storing hashed password instead of plain text.
To implement authentication you'll just need to hash the user's input and check the hashes.

How do I make private docs alongside public docs in a CouchDB database?

I'm somewhat new to CouchDB and I'm wondering how to make private docs, that is I want to have a database where all docs are public (rw, or r using a validate_doc_update) except for few/some selected docs, how would I do something like that?
And to complicate things a bit more I want them to be private to / accessible by the admin but also varying number of selected users (but no others).
I'm thinking that perhaps I could have two keys in these docs called "private" and "private_users", set them to true and [user1, user2, user3], and somehow use that info to make the docs private / only accessible by them.
So essentially it's about users being able to create docs and have them visible to everybody or just themselves and other selected users.
One way to do this would be to make the database private by setting the Security admin and members lists to the owner (making the database completely private), and then route all calls to reading documents through a backend script which checks these properties of the document through an admin account and fetches and returns the content if conditions are met, but the thing is I'd like to do this through configuring CouchDB and do CORS HTTPS calls from the clients browser directly to CouchDB, with no script in the middle.
Is this possible?
There are several potential solutions to this problem:
The problem: For a given user, allow only specific access to a given document in the database.
Database per user:
Create one database for each user and use authentication on the database for that given user. Because views do not work across databases, you will have to replicate all needed data between the different user databases to allow for a view to contain both private and public/other users' data. Because normal users can not create/delete databases, you will need to have a separate process running which watches your database for changes and creates a new user database when a new user registers.
Smart Proxy:
Create a smart proxy that wraps all documents with the user credentials and filters all results.
Document Encryption on a per User Basis:
This solution is described in a google document which was mentioned on the development mailinglist. The goal of this solution is to create a P2P like system, where you can replicate data to nodes which you don't trust.
validate_read_doc:
Have a javascript function be called on every read, in the same manner as the validate_doc_update system is applied.
For more information:
http://wiki.apache.org/couchdb/PerDocumentAuthorization
So essentially it's about users being able to create docs and have them visible to everybody or just themselves and other selected users ...... Is this possible?
Not with just couchdb...
The permissions that you set with _security in a database only apply write level security on it.
Other wise most of the documents (except the design documents) are available for every one to read. With validate functions
you can impose further restrictions on who writes the documents but again there is no way to check who is reading your documents.
rcouch has a validation on read which can help you what you want to do. Other wise if you want to go with couchdb you could use a proxy for communicating with it.

Fluent NHibernate - mapping portions of a single table into multiple classes with a few shared fields

I have a situation where a User table has lots of information about a user (first name, last name, email, etc) in addition to credential data (username, password, prior passwords, etc). Normally I would separate Authentication from Personalization, but this table is long established and I can't do that.
It bothers me to have 1 user object with all this data in it that is being passed around my application. I instead want to split this out into two objects: User and UserCredentials. User can be freely passed around my application without leaking any of the passwords, while UserCredentials will be used only in my services backend for validating and authenticate a user.
That seems simple enough. However, some fields need to be shared across both these objects. Will this cause issues with nhibernate when one of my objects is updated? For instance if a username change takes place and both have the username in the object, will both objects be updated?
If User and UserCredentials represent two views of the same entity, do not create two classes for them. It'll only lead to pain.
Alternatives:
Use a component to expose the "public" part of the entity and pass that
Use a DTO to contain exactly the fields you need and pass that

Storing a Windows SID in a Database for Lookup

I have an ASP.NET MVC application where I need to allow to customers configure MembershipProviders based on their environment, but still be able to map that MembershipUser to a concrete User model in our database.
Membership.GetUser() will give me access to the logged-in user's Membership.ProviderUserKey. I can use this to relate to a User record. Our custom SQL provider will just return the User.Id, but AD is a different story. In that case, ProviderUserKey is an IdentityReference.
These lookups will happen very frequently, as you can imagine (although caching can assist in reducing the lookups at the database level).
I can't decide which route is better to go: Storing the SID as a varbinary or varchar column. This column would not be a primary key and would not have a clustered index. Knowing that I can index strings pretty well, and reading a SID in string format is certainly nicer than binary. Anyone willing to share how they solved such a situation?
Update
I don't know how I missed this SO question when I was searching before I posted, but it seems pretty clear that ActiveDirectoryMembershipProvider and ActiveDirectoryMembershipUser are not quite cut out for the task at hand, as they exist today.
An answer in that SO question linked the following article, where the following was stated:
The relative identifier portion of a
SID is unique relative to the domain,
so if the domain changes, the relative
identifier also changes.
Thus when a User object moves from one
domain to another, a new SID must be
generated for the user account and
stored in the Object-SID property.
However, each group and user has an Object-GUID, which will never change, even if the account is moved. Therefore, it would behoove me to use Object-GUID in my User class, and not Object-SID. Otherwise, someone's User record will be abandoned if they are moved and therefore breaking the relationship between their principal and the data they created.
Unfortunately, ActiveDirectoryMembershipUser doesn't let me get at Object-GUID. So, I'll either have to translate the SID to a GUID after ActiveDirectoryMembershipUser does its work, or create my own MembershipProvider that does everything I need on the spot. Unfortunately, this means I might have to duplicate effort already done for me by ActiveDirectoryMembershipProvider.
Microsoft stores SIDs as varbinary(85) in sys.server_principals
This is also a unique column, so it must have an index...
username is the LAST thing you want to index on.
SIDs only change in an AD when you change a user from one domain to another. RIDs are split into 2 groups - inbuilt (< 1000) and user RIDs. Pre-defined users such as Administrator, Guest etc always have the same RID.
If you want to handle movement of users etc, then GUID is the way to go.
username can be changed at any time in Users and Groups management.
this is different to the object name, which is invariant, but I don't believe is mandated unique across a forest. You can have any number of John Smith users.
I'd look into the ADSI objects. These are COM objects which should be accessible from ASP. MSDN explains pretty well. an ADSearch object can be used to return user attributes (e.g. including DN) from a GUID.
Sounds like you're making this a lot more difficult than it needs to be. What do you need a SID or GUID for? You already have a unique, perfectly readable identifier for the users account maintained in ActiveDirectory.
It's called "the username". Hopefully it's the same username as stored in your apps "user" table.
Your app just needs to know if that username successfully authenticated with ActiveDirectory. So if they successfully log in - you just store the fact that they are authenticated in your Session variables.
If they are configured to use the db user login, if successful set the same Session variable indicating that they successfully logged in.
No fancy GUIDs or SIDs ... simple.