Skip to content
This repository was archived by the owner on May 21, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions arn/User.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/aerogo/aero"
"github.com/aerogo/http/client"
"github.com/akyoto/uuid"
"github.com/animenotifier/ffxiv"
"github.com/animenotifier/notify.moe/arn/autocorrect"
"github.com/animenotifier/notify.moe/arn/validate"
Expand Down Expand Up @@ -56,6 +57,7 @@ type User struct {
OS UserOS `json:"os" private:"true"`
Location *Location `json:"location" private:"true"`
FollowIDs []UserID `json:"follows"`
APIToken uuid.UUID `json:"apitoken" private:"true"`
Comment thread
AnnsAnns marked this conversation as resolved.
Outdated

hasPosts

Expand Down Expand Up @@ -137,6 +139,14 @@ func RegisterUser(user *User) {
}
}
}

// Create API Token
user.CreateAPIToken()
}

// (Re)create APIToken
func (user *User) CreateAPIToken() {
user.APIToken = uuid.New()
}

// SendNotification accepts a PushNotification and generates a new Notification object.
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ require (
github.com/akyoto/hash v0.4.10
github.com/akyoto/imageserver v0.3.7
github.com/akyoto/stringutils v0.3.1
github.com/akyoto/uuid v1.1.3
github.com/akyoto/webpush-go v0.1.2
github.com/animenotifier/anilist v0.2.6
github.com/animenotifier/ffxiv v0.2.2
Expand All @@ -46,6 +47,7 @@ require (
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/golang/protobuf v1.4.1 // indirect
github.com/gomodule/oauth1 v0.0.0-20181215000758-9a59ed3b0a84
github.com/google/uuid v1.1.2 // indirect
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/itchyny/gojq v0.6.0
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
Expand All @@ -63,6 +65,7 @@ require (
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/tebeka/strftime v0.1.4 // indirect
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf // indirect
github.com/tidwall/gjson v1.6.1
github.com/ungerik/go-gravatar v0.0.0-20120802094239-6ab22628222a
github.com/ventu-io/go-shortid v0.0.0-20171029131806-771a37caa5cf
github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
Expand Down Expand Up @@ -410,6 +412,12 @@ github.com/tebeka/strftime v0.1.4 h1:e0FKSyxthD1Xk4cIixFPoyfD33u2SbjNngOaaC3ePoU
github.com/tebeka/strftime v0.1.4/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/tidwall/gjson v1.6.1 h1:LRbvNuNuvAiISWg6gxLEFuCe72UKy5hDqhxW/8183ws=
github.com/tidwall/gjson v1.6.1/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/ungerik/go-gravatar v0.0.0-20120802094239-6ab22628222a h1:TZyMbJbyPL+4/ndyXns8aNDrmUJn5a6aV8lj3qEM7fM=
github.com/ungerik/go-gravatar v0.0.0-20120802094239-6ab22628222a/go.mod h1:cmQAsXze586z5DHYfoVO9jZBampncP3iuhVgujPqdxk=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
Expand Down
13 changes: 12 additions & 1 deletion pages/api/api.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package api

import (
"net/http"
"path"
"sort"

"github.com/aerogo/aero"
"github.com/akyoto/color"
"github.com/akyoto/uuid"
"github.com/animenotifier/notify.moe/arn"
"github.com/animenotifier/notify.moe/arn/autodocs"
"github.com/animenotifier/notify.moe/components"
Expand All @@ -14,6 +16,11 @@ import (
// Get api page.
func Get(ctx aero.Context) error {
types := []*autodocs.Type{}
user := arn.GetUserFromContext(ctx)

if user == nil {
return ctx.Error(http.StatusUnauthorized, "Not logged in")
}

for typeName := range arn.DB.Types() {
if typeName == "Session" {
Expand All @@ -33,5 +40,9 @@ func Get(ctx aero.Context) error {
return types[i].Name < types[j].Name
})

return ctx.HTML(components.API(types))
if (user.APIToken == uuid.UUID{}) {
user.CreateAPIToken()
}

return ctx.HTML(components.API(types, user))
}
5 changes: 4 additions & 1 deletion pages/api/api.pixy
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
component API(types []*autodocs.Type)
component API(types []*autodocs.Type, user *arn.User)
.api-docs
h1.mountable API

h2.mountable API Token
h3.mountable= user.APIToken.String()

h2.mountable Endpoints
ul
li.mountable
Expand Down
4 changes: 4 additions & 0 deletions server/New.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/animenotifier/notify.moe/server/graphql"
"github.com/animenotifier/notify.moe/server/https"
"github.com/animenotifier/notify.moe/server/middleware"
"github.com/animenotifier/notify.moe/server/tokenapi"
"github.com/animenotifier/notify.moe/utils/htmlemail"
"github.com/animenotifier/notify.moe/utils/routetests"
)
Expand Down Expand Up @@ -74,6 +75,9 @@ func New() *aero.Application {
// GraphQL
graphql.Install(app)

// Tokenapi
tokenapi.Install(app)
Comment thread
AnnsAnns marked this conversation as resolved.

// Close the database node on shutdown
app.OnEnd(arn.Node.Close)

Expand Down
35 changes: 35 additions & 0 deletions server/tokenapi/AnimeList.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tokenapi

import (
"errors"

"github.com/animenotifier/notify.moe/arn"
)

type AnimeParameters struct {
AnimeName string
Comment thread
AnnsAnns marked this conversation as resolved.
Outdated
AnimeID string
AnimeEpisode int
AnimeRating arn.AnimeRatingCount
}

func AnimeUpdate(request *TokenRequest) error {
parameters := &AnimeParameters{}
animeJSON := request.JSON.Get("anime")

parameters.AnimeName = animeJSON.Get("name").String()
parameters.AnimeID = animeJSON.Get("id").String()
parameters.AnimeEpisode = int(animeJSON.Get("episode").Int())

if parameters.AnimeName == "" && parameters.AnimeID == "" {
return errors.New("Neither ID nor Name of the anime has been supplied")
}

rating := animeJSON.Get("ratings")
parameters.AnimeRating.Overall = int(rating.Get("overall").Int())
parameters.AnimeRating.Story = int(rating.Get("story").Int())
parameters.AnimeRating.Visuals = int(rating.Get("visuals").Int())
parameters.AnimeRating.Soundtrack = int(rating.Get("soundtrack").Int())

return nil
}
18 changes: 18 additions & 0 deletions server/tokenapi/DBUtils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tokenapi

import (
"github.com/akyoto/uuid"
"github.com/animenotifier/notify.moe/arn"
)

func GetUserFromToken(token uuid.UUID) *arn.User {
user := &arn.User{}

for user = range arn.StreamUsers() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could replace this O(n) loop with an O(1) lookup using a new collection in the DB ("TokenToUser") later on.

Otherwise this can become a huge bottleneck.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally wanted to implement this in a better way but I'm honestly too unfamiliar with nano so I didn't want to touch what I was unsure about.

if user.APIToken == token {
break
}
}

return user
}
18 changes: 18 additions & 0 deletions server/tokenapi/Install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package tokenapi

import (
"os"

"github.com/aerogo/aero"
"github.com/aerogo/log"
)

// Install installs all authentication routes in the application.
func Install(app *aero.Application) {
authLog := log.New()
authLog.AddWriter(os.Stdout)
authLog.AddWriter(log.File("logs/tokenapi.log"))

// Login
Main(app, authLog)
}
50 changes: 50 additions & 0 deletions server/tokenapi/Main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package tokenapi

import (
"github.com/aerogo/aero"
"github.com/aerogo/log"
"github.com/akyoto/uuid"
"github.com/animenotifier/notify.moe/arn"
"github.com/tidwall/gjson"
Comment thread
AnnsAnns marked this conversation as resolved.

"net/http"
)

type TokenRequest struct {
Token uuid.UUID
User arn.User

JSON gjson.Result
}

func Main(app *aero.Application, log *log.Log) {
app.Post("/tokenapi", func(ctx aero.Context) error {
response, err := ctx.Request().Body().String()
if err != nil {
Comment thread
AnnsAnns marked this conversation as resolved.
return ctx.Error(http.StatusBadRequest, "Couldn't get body", err)
}
if !gjson.Valid(response) {
return ctx.Error(http.StatusBadRequest, "Couldn't parse JSON")
}

request := &TokenRequest{}
request.JSON = gjson.Parse(response)

token, err := uuid.Parse(request.JSON.Get("token").String())
if err != nil {
return ctx.Error(http.StatusBadRequest, "Couldn't parse token", err)
}
request.Token = token
request.User = *GetUserFromToken(token)

action := request.JSON.Get("action").String()
if action == "UpdateAnime" {
err := AnimeUpdate(request)
if err != nil {
return ctx.Error(http.StatusBadRequest, "Error updating anime:", err)
}
}

return ctx.Error(http.StatusAccepted, "Processed request for", request.User.CleanNick())
})
}