Coder Social home page Coder Social logo

davidgraeff / firestore-db-and-auth-rs Goto Github PK

View Code? Open in Web Editor NEW
95.0 95.0 35.0 222 KB

Easy Rust access to your Google Firestore DB via service account or OAuth impersonated Google Firebase Auth credentials

License: MIT License

Rust 98.90% Shell 1.10%
authentication firebase firestore

firestore-db-and-auth-rs's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

firestore-db-and-auth-rs's Issues

Support for local storage emulator

Is your feature request related to a problem? Please describe.
Good development practice is to use local database in local environment. Postgres and Firestore running locally is ideal.

Describe the solution you'd like
Ability to configure the credentials to point to the local firestore emulator.

Describe alternatives you've considered
N/A

Additional context
N/A

Better naming convention for `Result` type alias in `errors` module

Is your feature request related to a problem? Please describe.

Would it be possible to have a better type alias name for the firestore_db_and_auth::errors::Result type? As a relative newcomer to Rust this was extremely unclear how to use this. Currently the module errors declares a type alias that is intended to capture a variety of different errors (see original source code)

// Current implementation
pub type Result<T> = std::result::Result<T, FirebaseError>;

It was very unclear to me that where I would call operations like document::read() that I had to use the module's Result and not std::result. This is not clearly laid out in the documentation anywhere. Based on the example below, I'm not sure that the intention of this change lead to better ergonomics

// Incorrect
let result: Result<MyFirestoreUser, firestore_db_and_auth::errors::FirebaseError> = documents::read(&session, "user", "123456");

// Correct
let result: firestore_db_and_auth::errors::Result<MyFirestoreUser> = documents::read(&session, "user", "123456");

Describe the solution you'd like

Perhaps just declare this alias as something more specific to this crate FirestoreResult?

I think this keeps the ergonomic efficiency and also makes it clear you're getting a different Rust type as a result of the operation.

let result: FirestoreResult<MyFirestoreUser> = documents::read(&session, "user", "123456");

Describe alternatives you've considered

Is there a way to import this type into lib/main.rs so that I don't have to properly scope every call to firestore_db_and_auth:errors::Result

Additional context

Running on v0.6.0

Project Maintained?

I'm seeing a few issues in this project that I would consider to be critical but haven't seen a lot of activity from the maintainers of this project for quite awhile. Is this project still actively maintained?

FirestoreAuthSessionGuard should report proper failures or forwards

Is your feature request related to a problem? Please describe.
The rocket request guard will always pass the outcome forward if there is a missing Authorization header, the header is missing "Bearer", and if the token itself is invalid.

Describe the solution you'd like
Depending on how your project is set up, many times this will cause the request to get caught in one of the catchers the user has defined. Most commonly I've seen 404 not found. I believe the module should be reporting back failures with the Status::Unauthorized. Similar to how you force the Outcome as "Internal Server Error" when the underlying credentials object has not yet been set.

Describe alternatives you've considered
According to rocketrs documentation there doesn't seem to be any way to catch these "forwards" unless they have some "status" associated with it.

Additional context
For example: If the module were to return a failure or forward with the content Status::Unauthorized, the developer using rocket could catch it with a #[catch(401)] so it can properly be returning the end user.

"start at" and "orderby" examples

Could you give an example on how to make a document query with "start at" and "order by"?

Thanks, this library looks really nice by the way.

already mutably borrowed: BorrowError

Describe the bug

My program did stop with the following error:

thread 'tokio-runtime-worker' panicked at 'already mutably borrowed: BorrowError', /Users/yfleury/.cargo/registry/src/github.com-1ecc6299db9ec823/firestore-db-and-auth-0.6.1/src/sessions.rs:308:45

Looking at the sessions.rs line (308 in the log, 488 in this repo source code) it seems that the call to .borrow() is panicking.

image

I'm kind of new to Rust so I'm not sure everything is right on my side.

To Reproduce

Here is my program https://github.com/BearStudio/twitch-listener

Steps to reproduce the behavior:

  1. Run with cargo run
  2. Use documents like
struct Question {
    id: String,
    username: String,
    message: String,
    timestamp: String,
}

Expected behavior

I expect my program not to panic.

Empty `mapValue` in response causes JSON parser error

Describe the bug
When attempting to parse a Firestore document whose mapValue returns an empty JSON object parsing fails and causes a reqwest Decode error because the required fields key cannot be found. Note that it is possible to have Firestore doc with a map value that is an empty object.

This appears to originate in the type definition of MapValue because it will not currently accept an Option type and must have fields present in the JSON response. Current definition:

pub struct MapValue {
    pub fields: HashMap<String, Value>,
}

When it should be

pub struct MapValue {
    pub fields: Option<HashMap<String, Value>>,
}

To Reproduce

Create a Firestore document that contains an object whose values are empty like this:

{
  "name": "projects/firestore-db-and-auth/databases/(default)/documents/user/1",
  "fields": {
    "gender": {
      "stringValue": "male"
    },
   "age": {
      "integerValue": "35"
    },
    "profile": {
       "mapValue": {}
    }
  },
  "createTime": "2020-04-28T14:52:51.250511Z",
  "updateTime": "2020-04-28T14:52:51.250511Z"
}

See that when this document is parsed via the crate, it raises an error of errors::Request masked underneath a reqwest error:

reqwest::Error {
  kind: Decode,
  source: Error("missing field `fields`", line: 77, column: 26),
}

Note that the line number will vary as the ordering of the fields in the document changes in each HTTP response.

Expected behavior

This does not cause an error and allows for an empty mapValue object from the Firestore document

Get metadata of listed documents

If I understand correctly, documents::list will return an iterator of structs that mirror the content of the documents. Is there any way to get the metadata (e.g. names) of the documents in a collection?

Add create session cookie feature

Hello,

Thanks for sharing this rust library !

But it seems like we cannot create a session cookie with this library.

It should be nice to be able to create a session cookie like described in the firebase documentation : https://firebase.google.com/docs/auth/admin/manage-cookies#create_session_cookie

I created a PR to add this feature by looking at the source code of firebase-admin-node :
https://github.com/firebase/firebase-admin-node/blob/master/src/auth/auth-api-request.ts#L971
https://github.com/firebase/firebase-admin-node/blob/master/src/auth/auth-api-request.ts#L1711

Any feedback are welcome !

documents::delete does not report failures

When a document::write fails (e.g. because of missing permissions), the function correctly returns an Err Result. In contract, it seems to me that document::delete always returns Ok even when the delete failed.

Create user with displayName

Hello, im creating user with e-mail is there a way to add displayName field, or is read-only from firebase?
I'm using sign_up(&session, email, password) to create user.

Async/Await support

As soon as Rust 1.39 hits stable and the used reqwest crate is released with async support, this library should be updated to offer blocking and async APIs.

Access tokens created from UserSession::by_user_id cannot be used with UserSession::by_access_token

Describe the bug

The code below

     let sess = UserSession::by_user_id(&cred, &format!("test_{}", uid), false)
        .expect("failed to create a user session");

    let token = sess.access_token();
    UserSession::by_access_token(&cred, &token).expect("invalid test token");

panic with invalid test token: Generic("No secret for kid")

The header of created jwt is

{
  "alg": "RS256",
  "kid": "tB0M2A"
}

To Reproduce
Steps to reproduce the behavior:

  1. Create an access token with UserSession::by_user_id
  2. Pass the access token to UserSession::by_access_token

Expected behavior
Works without any issue.

Fails while installing crate due a conflict with ring crate

I'm not sure if this is an actual error or I'm doing something wrong but while attempting to install the crate it fails and displays an error related to the ring crate.

Cargo.toml

[package]
name = "my_project"
version = "0.1.0"
authors = ["megustalafantabienfria"]
edition = "2018"

[dependencies]
rocket = "0.4.4"
firestore-db-and-auth = "0.6.0"

[dependencies.rocket_contrib]
version = "0.4.4"
default-features = false
features = ["json"]

And this what the console displays

 > cargo run
    Blocking waiting for file lock on package cache
    Updating crates.io index
error: failed to select a version for `ring`.
    ... required by package `biscuit v0.4.0`
    ... which is depended on by `firestore-db-and-auth v0.6.0`
    ... which is depended on by `my_project v0.1.0 (project path)`
versions that meet the requirements `^0.16.5` are: 0.16.13, 0.16.12, 0.16.11, 0.16.10, 0.16.9, 0.16.7, 0.16.6, 0.16.5

the package `ring` links to the native library `ring-asm`, but it conflicts with a previous package which links to `ring-asm` as well:
package `ring v0.13.5`
    ... which is depended on by `cookie v0.11.2`
    ... which is depended on by `rocket_http v0.4.4`
    ... which is depended on by `rocket v0.4.4`
    ... which is depended on by `my_project v0.1.0 (project path)`

failed to select a version for `ring` which could resolve this conflict

session_cookie::create cannot create long lived cookies

Describe the bug
The createSessionCookie REST API supports a validDuration between five minutes and fourteen days. Ref https://cloud.google.com/identity-platform/docs/reference/rest/v1/projects/createSessionCookie

Using session_cookie::create to obtain a session cookie it is not possible to retrieve a cookie with a duration greater than sixty minutes.

This is caused because of the below line which reuses the cookie duration when requesting a OAuth token.

        let assertion = crate::jwt::session_cookie::create_jwt_encoded(credentials, duration)?;

The request for the OAuth token (POST https://accounts.google.com/o/oauth2/token) with a duration greater than sixty minutes will return:

{
  "error":"invalid_grant",
  "error_description":"Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim."
}

Specifying a duration less than sixty minutes for session_cookie::create will work as expected.

I propose that as the a oauth token is requested every time session_cookie::create is called the JWT duration for getting the oauth token should be reduced to a constant between one to five minutes.

To Reproduce
Steps to reproduce the behavior:

  1. call session_cookie::create with a duration more than sixty minutes.

Expected behavior
A duration between five and fourteen days should return successfully.

Remove Cargo.lock from git?

As far as I know, it's recommended to include Cargo.lock in git for binary crates but not for lib crates. Could it be removed and .gitignored, or is there a special reason to include it?

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.