diff --git a/README.md b/README.md index 63b6ad51..4d5878ca 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,36 @@ -# discours-backend-next - -Tech stack: - - - pyjwt - - redis - - ariadne - - starlette - -# Local development - -Install redis and pipenv first - -``` -brew install redis pipenv -brew services start redis -``` - -Create certificate files - -```sh -./create_crt.sh -``` - -Then run API server - -``` -pipenv install -pipenv run python server.py -``` - -Also see `Dockerfile` - -# How to do an authorized request - -Put the header 'Auth' with token from signInQuery or registerQuery. \ No newline at end of file +# discours-backend-next + +Tech stack: + +- pyjwt +- redis +- ariadne +- starlette + +# Local development + +Install redis and pipenv first + +``` +brew install redis pipenv +brew services start redis +``` + +Create certificate files + +```sh +./create_crt.sh +``` + +Then run API server + +``` +pipenv install +pipenv run python server.py +``` + +Also see `Dockerfile` + +# How to do an authorized request + +Put the header 'Auth' with token from signInQuery or registerQuery. diff --git a/auth/README.md b/auth/README.md index 68dfec9c..8629a3d9 100644 --- a/auth/README.md +++ b/auth/README.md @@ -1,9 +1,9 @@ -## Based on +## Based on -* pyjwt -* [ariadne](https://github.com/mirumee/ariadne) -* [aioredis](https://github.com/aio-libs/aioredis) -* [starlette](https://github.com/encode/starlette)、 -* sqlalchmy ORM +- pyjwt +- [ariadne](https://github.com/mirumee/ariadne) +- [aioredis](https://github.com/aio-libs/aioredis) +- [starlette](https://github.com/encode/starlette)、 +- sqlalchmy ORM token is valid for one day, user can choose to logout, logout is revoke token diff --git a/migration/README.md b/migration/README.md index caaac573..a10d92ba 100644 --- a/migration/README.md +++ b/migration/README.md @@ -10,10 +10,10 @@ pipenv install -r requirements.txt ## Using -Put the unpacked mongodump to the `data` folder and operate with `pipenv shell && python` +Put the unpacked mongodump to the `data` folder and operate with +`pipenv shell && python` - -1. get old data jsons +1. get old data jsons ```py import bson2json @@ -23,19 +23,16 @@ bson2json.json_tables() # creates all the needed data json from bson mongodump 2. migrate users -```py -import json -from migrations.users import migrate +```sh +pipenv run python migrate.py users +``` +Note: this will create db entries and it is not tolerant to existed unique email. -data = json.loads(open('data/users.json').read()) -newdata = {} +3. then topics and shouts -for u in data: - try: - newdata[u['_id']] = migrate(u) - except: - print('FAIL!') - print(u) +```sh +pipenv run python migrate.py topics +pipenv run python migrate.py shouts +``` - -``` \ No newline at end of file +Now you got the *.dict.json files which contain all the data with old and new(!) ids. \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index 3c1cc85e..e19d0be5 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1,242 +1,241 @@ -scalar DateTime - -################################### Payload - -type Result { - error: String -} - -type AuthResult { - error: String - token: String - user: User -} - -type UserResult { - error: String - user: User -} - -type MessageResult { - error: String - message: Message -} - -input ShoutInput { - org_id: Int! - slug: String! - body: String! - replyTo: String # another shout - tags: [String] # actual values - topics: [String] # topic-slugs - title: String - versionOf: String - visibleForRoles: [String] # role ids are strings - visibleForUsers: [Int] -} - -input ProfileInput { - email: String - username: String - userpic: String -} - -type ShoutResult { - error: String - shout: Shout -} - -################################### Mutation - -type Mutation { - # message - createMessage(body: String!, replyTo: Int): MessageResult! - updateMessage(id: Int!, body: String!): MessageResult! - deleteMessage(messageId: Int!): Result! - - # auth - confirmEmail(token: String!): AuthResult! - requestPasswordReset(email: String!): Boolean! - confirmPasswordReset(token: String!): Boolean! - registerUser(email: String!, password: String!): AuthResult! - # updatePassword(password: String!, token: String!): Token! - # invalidateAllTokens: Boolean! - # invalidateTokenById(id: Int!): Boolean! - # requestEmailConfirmation: User! - - # shout - createShout(input: ShoutInput!): ShoutResult! - updateShout(input: ShoutInput!): ShoutResult! - deleteShout(slug: String!): Result! - rateShout(slug: String!, value: Int!): Result! - - # user profile - # rateUser(value: Int!): Result! - # updateOnlineStatus: Result! - updateProfile(profile: ProfileInput!): Result! -} - -################################### Query - -type Query { - # auth - isEmailFree(email: String!): Result! - signIn(email: String!, password: String!): AuthResult! - signOut: Result! - # user profile - getCurrentUser: UserResult! - getUserById(id: Int!): UserResult! - # getUserRating(shout: Int): Int! - - # messages - getMessages(count: Int = 100, page: Int = 1): [Message!]! - - # shouts - # getShoutRating(shout: Int): Int! - # shoutsByAuthor(author: Int): [Shout]! - # shoutsByReplyTo(shout: Int): [Shout]! - # shoutsByTags(tags: [String]): [Shout]! - # shoutsByTime(time: DateTime): [Shout]! - - # getOnlineUsers: [User!]! - topAuthors: [User]! - topShouts: [Shout]! -} - -############################################ Subscription - -type Subscription { - messageCreated: Message! - messageUpdated: Message! - messageDeleted: Message! - - onlineUpdated: [User!]! - shoutUpdated: Shout! - userUpdated: User! -} - -############################################ Entities - -type Role { - id: Int! - name: String! - org_id: Int! - # level: Int! # 1-8 - desc: String - permissions: [Int!]! -} - -type Rating { - createdBy: String! - value: Int! -} - -type Notification { - kind: String! # unique primary key - template: String! - variables: [String] -} - -type UserNotification { - id: Int! # primary key - user: Int! - kind: String! # NotificationTemplate.name - values: [String] -} - -type User { - username: String! # email - createdAt: DateTime! - email: String - password: String - oauth: String # provider:token - viewname: String # to display - userpic: String - links: [String] - emailConfirmed: Boolean # should contain all emails too # TODO: pagination here - id: Int! - muted: Boolean - rating: Int - roles: [Role] - updatedAt: DateTime - wasOnlineAt: DateTime - ratings: [Rating] - slug: String - bio: String - notifications: [Int] -} - -type Message { - author: Int! - body: String! - createdAt: DateTime! - id: Int! - replyTo: Int - updatedAt: DateTime! - visibleForUsers: [Int]! -} - -# is publication -type Shout { - slug: String! - authors: [Int!]! - body: String! - org_id: Int - cover: String - layout: String - createdAt: DateTime! - updatedAt: DateTime - deletedAt: DateTime - deletedBy: Int - rating: Int - ratigns: [Rating] - published: Boolean - publishedAt: DateTime # if there is no published field - it is not published - replyTo: String # another shout - tags: [String] # actual values - topics: [String] # topic-slugs, order has matter - title: String - subtitle: String - versionOf: String - visibleForRoles: [String] # role ids are strings - visibleForUsers: [Int] - views: Int -} - -type Topic { - slug: String! # ID - createdBy: Int! # User - createdAt: DateTime! - value: String - desc: String - parents: [String] # NOTE: topic can have parent topics - children: [String] # and children -} - -# TODO: resolvers to add/remove topics from publication - - -type Proposal { - body: String! - shout: Int! - range: String # full / 0:2340 - author: Int! - createdAt: DateTime! -} - -type Token { - createdAt: DateTime! - expiresAt: DateTime - id: Int! - ownerId: Int! - usedAt: DateTime - value: String! -} - -type Like { - author: Int! - id: Int! - value: Int! - shout: Int - user: Int -} +scalar DateTime + +################################### Payload + +type Result { + error: String +} + +type AuthResult { + error: String + token: String + user: User +} + +type UserResult { + error: String + user: User +} + +type MessageResult { + error: String + message: Message +} + +input ShoutInput { + org_id: Int! + slug: String! + body: String! + replyTo: String # another shout + tags: [String] # actual values + topics: [String] # topic-slugs + title: String + versionOf: String + visibleForRoles: [String] # role ids are strings + visibleForUsers: [Int] +} + +input ProfileInput { + email: String + username: String + userpic: String +} + +type ShoutResult { + error: String + shout: Shout +} + +################################### Mutation + +type Mutation { + # message + createMessage(body: String!, replyTo: Int): MessageResult! + updateMessage(id: Int!, body: String!): MessageResult! + deleteMessage(messageId: Int!): Result! + + # auth + confirmEmail(token: String!): AuthResult! + requestPasswordReset(email: String!): Boolean! + confirmPasswordReset(token: String!): Boolean! + registerUser(email: String!, password: String!): AuthResult! + # updatePassword(password: String!, token: String!): Token! + # invalidateAllTokens: Boolean! + # invalidateTokenById(id: Int!): Boolean! + # requestEmailConfirmation: User! + + # shout + createShout(input: ShoutInput!): ShoutResult! + updateShout(input: ShoutInput!): ShoutResult! + deleteShout(slug: String!): Result! + rateShout(slug: String!, value: Int!): Result! + + # user profile + # rateUser(value: Int!): Result! + # updateOnlineStatus: Result! + updateProfile(profile: ProfileInput!): Result! +} + +################################### Query + +type Query { + # auth + isEmailFree(email: String!): Result! + signIn(email: String!, password: String!): AuthResult! + signOut: Result! + # user profile + getCurrentUser: UserResult! + getUserById(id: Int!): UserResult! + # getUserRating(shout: Int): Int! + + # messages + getMessages(count: Int = 100, page: Int = 1): [Message!]! + + # shouts + # getShoutRating(shout: Int): Int! + # shoutsByAuthor(author: Int): [Shout]! + # shoutsByReplyTo(shout: Int): [Shout]! + # shoutsByTags(tags: [String]): [Shout]! + # shoutsByTime(time: DateTime): [Shout]! + + # getOnlineUsers: [User!]! + topAuthors: [User]! + topShouts: [Shout]! +} + +############################################ Subscription + +type Subscription { + messageCreated: Message! + messageUpdated: Message! + messageDeleted: Message! + + onlineUpdated: [User!]! + shoutUpdated: Shout! + userUpdated: User! +} + +############################################ Entities + +type Role { + id: Int! + name: String! + org_id: Int! + # level: Int! # 1-8 + desc: String + permissions: [Int!]! +} + +type Rating { + createdBy: String! + value: Int! +} + +type Notification { + kind: String! # unique primary key + template: String! + variables: [String] +} + +type UserNotification { + id: Int! # primary key + user: Int! + kind: String! # NotificationTemplate.name + values: [String] +} + +type User { + username: String! # email + createdAt: DateTime! + email: String + password: String + oauth: String # provider:token + viewname: String # to display + userpic: String + links: [String] + emailConfirmed: Boolean # should contain all emails too # TODO: pagination here + id: Int! + muted: Boolean + rating: Int + roles: [Role] + updatedAt: DateTime + wasOnlineAt: DateTime + ratings: [Rating] + slug: String + bio: String + notifications: [Int] +} + +type Message { + author: Int! + body: String! + createdAt: DateTime! + id: Int! + replyTo: Int + updatedAt: DateTime! + visibleForUsers: [Int]! +} + +# is publication +type Shout { + slug: String! + authors: [Int!]! + body: String! + org_id: Int + cover: String + layout: String + createdAt: DateTime! + updatedAt: DateTime + deletedAt: DateTime + deletedBy: Int + rating: Int + ratigns: [Rating] + published: Boolean + publishedAt: DateTime # if there is no published field - it is not published + replyTo: String # another shout + tags: [String] # actual values + topics: [String] # topic-slugs, order has matter + title: String + subtitle: String + versionOf: String + visibleForRoles: [String] # role ids are strings + visibleForUsers: [Int] + views: Int +} + +type Topic { + slug: String! # ID + createdBy: Int! # User + createdAt: DateTime! + value: String + desc: String + parents: [String] # NOTE: topic can have parent topics + children: [String] # and children +} + +# TODO: resolvers to add/remove topics from publication + +type Proposal { + body: String! + shout: Int! + range: String # full / 0:2340 + author: Int! + createdAt: DateTime! +} + +type Token { + createdAt: DateTime! + expiresAt: DateTime + id: Int! + ownerId: Int! + usedAt: DateTime + value: String! +} + +type Like { + author: Int! + id: Int! + value: Int! + shout: Int + user: Int +}