...
1 package barcode
2
3 import (
4 "context"
5
6 "github.com/ory/fosite"
7 "github.com/ory/fosite/handler/openid"
8 "github.com/ory/x/errorsx"
9 "golang.org/x/crypto/bcrypt"
10
11 "edge-infra.dev/pkg/edge/iam/config"
12 "edge-infra.dev/pkg/edge/iam/prometheus"
13 "edge-infra.dev/pkg/edge/iam/util"
14 )
15
16 type ScopeHandler struct {
17 BarcodeGenStrategy Strategy
18 BarcodeStorage Storage
19
20 Metrics *prometheus.Metrics
21 }
22
23 func (h *ScopeHandler) HandleTokenEndpointRequest(_ context.Context, request fosite.AccessRequester) error {
24 if !request.GetClient().GetGrantTypes().Has("barcode") {
25 return errorsx.WithStack(fosite.ErrUnauthorizedClient.WithHint("The OAuth 2.0 Client is not allowed to use scope 'barcode'."))
26 }
27 h.Metrics.IncHTTPRequestsTotal(signUpBarcodeScope)
28 return nil
29 }
30 func (h *ScopeHandler) CanHandleTokenEndpointRequest(requester fosite.AccessRequester) bool {
31 return requester.GetGrantedScopes().Has("barcode") && !requester.GetGrantTypes().ExactOne("barcode")
32 }
33 func (h *ScopeHandler) PopulateTokenEndpointResponse(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) (err error) {
34 if !h.CanHandleTokenEndpointRequest(requester) {
35 return errorsx.WithStack(fosite.ErrUnknownRequest)
36 }
37 barcode, err := h.BarcodeGenStrategy.Generate()
38 if err != nil {
39 return errorsx.WithStack(fosite.ErrServerError.WithHint("encountered internal server error"))
40 }
41 openIDSession, ok := requester.GetSession().(openid.Session)
42 if !ok {
43 return errorsx.WithStack(fosite.ErrInvalidGrant.WithHint("should be an openID session"))
44 }
45 key := h.BarcodeGenStrategy.GetKey(barcode)
46 if err = h.BarcodeStorage.CreateBarcodeUser(ctx, openIDSession.IDTokenClaims().Subject, key); err != nil {
47 return errorsx.WithStack(fosite.ErrServerError)
48 }
49
50 barcodePrefixLen := uint8(len(config.BarcodePrefix()))
51 secret := barcode[barcodePrefixLen+config.GetBarcodeKeyLength():]
52 hash, _ := bcrypt.GenerateFromPassword([]byte(secret), config.BcryptCost())
53 if err := h.BarcodeStorage.CreateBarcode(ctx, key, string(hash), openIDSession.IDTokenClaims().Subject); err != nil {
54 return err
55 }
56 responder.SetExtra("barcode", barcode)
57 h.Metrics.IncSignUpRequestsTotal(signUpBarcodeScope, util.Succeeded)
58 return nil
59 }
60 func (h *ScopeHandler) CanSkipClientAuth(_ fosite.AccessRequester) bool {
61 return false
62 }
63
View as plain text