Skip to content

Commit

Permalink
add api key testing to profile api
Browse files Browse the repository at this point in the history
  • Loading branch information
greenpau committed Mar 22, 2024
1 parent c5d0307 commit 86bec33
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 20 deletions.
83 changes: 83 additions & 0 deletions pkg/authn/api_test_user_api_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2024 Paul Greenberg [email protected]
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package authn

import (
"context"
"net/http"

"github.com/greenpau/go-authcrunch/pkg/authn/enums/operator"
"github.com/greenpau/go-authcrunch/pkg/identity"
"github.com/greenpau/go-authcrunch/pkg/ids"
"github.com/greenpau/go-authcrunch/pkg/requests"
"github.com/greenpau/go-authcrunch/pkg/user"
)

// TestUserAPIKey tests API key.
func (p *Portal) TestUserAPIKey(
ctx context.Context,
w http.ResponseWriter,
r *http.Request,
rr *requests.Request,
parsedUser *user.User,
resp map[string]interface{},
usr *user.User,
backend ids.IdentityStore,
bodyData map[string]interface{}) error {

rr.Key.Usage = "api"

var keyContent string

// Extract data.
if v, exists := bodyData["id"]; exists {
switch keyID := v.(type) {
case string:
rr.Key.ID = keyID
default:
resp["message"] = "Profile API did find key id in the request payload, but it is malformed"
return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp)
}
} else {
resp["message"] = "Profile API did not find key id in the request payload"
return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp)
}
if v, exists := bodyData["content"]; exists {
switch exp := v.(type) {
case string:
keyContent = exp
default:
resp["message"] = "Profile API did find key content in the request payload, but it is malformed"
return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp)
}
} else {
resp["message"] = "Profile API did not find key content in the request payload"
return handleAPIProfileResponse(w, rr, http.StatusBadRequest, resp)
}

if err := backend.Request(operator.GetAPIKey, rr); err != nil {
resp["message"] = "Profile API failed to get API key"
return handleAPIProfileResponse(w, rr, http.StatusInternalServerError, resp)
}
apiKey := rr.Response.Payload.(*identity.APIKey)

if !apiKey.Match(keyContent) {
resp["message"] = "Profile API failed to validate provided API key"
return handleAPIProfileResponse(w, rr, http.StatusInternalServerError, resp)
}

resp["entry"] = "OK"
return handleAPIProfileResponse(w, rr, http.StatusOK, resp)
}
3 changes: 3 additions & 0 deletions pkg/authn/handle_api_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func (p *Portal) handleAPIProfile(ctx context.Context, w http.ResponseWriter, r
case "fetch_user_api_key":
case "delete_user_api_key":
case "add_user_api_key":
case "test_user_api_key":
case "fetch_user_ssh_keys":
case "fetch_user_ssh_key":
case "delete_user_ssh_key":
Expand Down Expand Up @@ -201,6 +202,8 @@ func (p *Portal) handleAPIProfile(ctx context.Context, w http.ResponseWriter, r
return p.DeleteUserAPIKey(ctx, w, r, rr, parsedUser, resp, usr, backend, bodyData)
case "add_user_api_key":
return p.AddUserAPIKey(ctx, w, r, rr, parsedUser, resp, usr, backend, bodyData)
case "test_user_api_key":
return p.TestUserAPIKey(ctx, w, r, rr, parsedUser, resp, usr, backend, bodyData)
case "fetch_user_ssh_keys":
return p.FetchUserSSHKeys(ctx, w, r, rr, parsedUser, resp, usr, backend)
case "fetch_user_ssh_key":
Expand Down
42 changes: 25 additions & 17 deletions pkg/identity/api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
package identity

import (
"time"

"github.com/greenpau/go-authcrunch/pkg/errors"
"github.com/greenpau/go-authcrunch/pkg/requests"
"github.com/greenpau/go-authcrunch/pkg/tagging"
"github.com/greenpau/go-authcrunch/pkg/util"
"golang.org/x/crypto/bcrypt"
"time"
)

// APIKeyBundle is a collection of API keys.
Expand All @@ -30,16 +32,19 @@ type APIKeyBundle struct {

// APIKey is an API key.
type APIKey struct {
ID string `json:"id,omitempty" xml:"id,omitempty" yaml:"id,omitempty"`
Prefix string `json:"prefix,omitempty" xml:"prefix,omitempty" yaml:"prefix,omitempty"`
Usage string `json:"usage,omitempty" xml:"usage,omitempty" yaml:"usage,omitempty"`
Comment string `json:"comment,omitempty" xml:"comment,omitempty" yaml:"comment,omitempty"`
Payload string `json:"payload,omitempty" xml:"payload,omitempty" yaml:"payload,omitempty"`
Expired bool `json:"expired,omitempty" xml:"expired,omitempty" yaml:"expired,omitempty"`
ExpiredAt time.Time `json:"expired_at,omitempty" xml:"expired_at,omitempty" yaml:"expired_at,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty" xml:"created_at,omitempty" yaml:"created_at,omitempty"`
Disabled bool `json:"disabled,omitempty" xml:"disabled,omitempty" yaml:"disabled,omitempty"`
DisabledAt time.Time `json:"disabled_at,omitempty" xml:"disabled_at,omitempty" yaml:"disabled_at,omitempty"`
ID string `json:"id,omitempty" xml:"id,omitempty" yaml:"id,omitempty"`
Prefix string `json:"prefix,omitempty" xml:"prefix,omitempty" yaml:"prefix,omitempty"`
Usage string `json:"usage,omitempty" xml:"usage,omitempty" yaml:"usage,omitempty"`
Comment string `json:"comment,omitempty" xml:"comment,omitempty" yaml:"comment,omitempty"`
Payload string `json:"payload,omitempty" xml:"payload,omitempty" yaml:"payload,omitempty"`
Expired bool `json:"expired,omitempty" xml:"expired,omitempty" yaml:"expired,omitempty"`
ExpiredAt time.Time `json:"expired_at,omitempty" xml:"expired_at,omitempty" yaml:"expired_at,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty" xml:"created_at,omitempty" yaml:"created_at,omitempty"`
Disabled bool `json:"disabled,omitempty" xml:"disabled,omitempty" yaml:"disabled,omitempty"`
DisabledAt time.Time `json:"disabled_at,omitempty" xml:"disabled_at,omitempty" yaml:"disabled_at,omitempty"`
Description string `json:"description,omitempty" xml:"description,omitempty" yaml:"description,omitempty"`
Tags []tagging.Tag `json:"tags,omitempty" xml:"tags,omitempty" yaml:"tags,omitempty"`
Labels []string `json:"labels,omitempty" xml:"labels,omitempty" yaml:"labels,omitempty"`
}

// NewAPIKeyBundle returns an instance of APIKeyBundle.
Expand Down Expand Up @@ -80,12 +85,15 @@ func NewAPIKey(r *requests.Request) (*APIKey, error) {
return nil, errors.ErrAPIKeyCommentEmpty
}
p := &APIKey{
Comment: r.Key.Comment,
ID: util.GetRandomString(40),
Prefix: r.Key.Prefix,
Payload: r.Key.Payload,
Usage: r.Key.Usage,
CreatedAt: time.Now().UTC(),
Comment: r.Key.Comment,
ID: util.GetRandomString(40),
Prefix: r.Key.Prefix,
Payload: r.Key.Payload,
Usage: r.Key.Usage,
CreatedAt: time.Now().UTC(),
Description: r.Key.Description,
Tags: r.Key.Tags,
Labels: r.Key.Labels,
}
if r.Key.Disabled {
p.Disabled = true
Expand Down
4 changes: 2 additions & 2 deletions pkg/identity/mfa_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ func (p *MfaToken) WebAuthnRequest(payload string) (*WebAuthnAuthenticateRequest
}

// Verify that the value of C.crossOrigin is false.
if r.ClientData.CrossOrigin == true {
if r.ClientData.CrossOrigin {
return r, errors.ErrWebAuthnRequest.WithArgs("client data cross origin true is not supported")
}

Expand All @@ -438,7 +438,7 @@ func (p *MfaToken) WebAuthnRequest(payload string) (*WebAuthnAuthenticateRequest
}

// Verify that the User Present bit of the flags in authData is set.
if r.AuthData.Flags["UP"] != true {
if !r.AuthData.Flags["UP"] {
return r, errors.ErrWebAuthnRequest.WithArgs("authData User Present bit is not set")
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/ids/local/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ func (b *IdentityStore) Request(op operator.Type, r *requests.Request) error {
case operator.DeletePublicKey:
return b.authenticator.DeletePublicKey(r)
case operator.AddMfaToken:
// b.logger.Debug("detected supported identity store operation", zap.Any("op", op), zap.Any("params", r))
return b.authenticator.AddMfaToken(r)
case operator.DeleteMfaToken:
return b.authenticator.DeleteMfaToken(r)
Expand All @@ -132,8 +131,12 @@ func (b *IdentityStore) Request(op operator.Type, r *requests.Request) error {
return b.authenticator.DeleteAPIKey(r)
case operator.GetPublicKeys:
return b.authenticator.GetPublicKeys(r)
case operator.GetPublicKey:
return b.authenticator.GetPublicKey(r)
case operator.GetAPIKeys:
return b.authenticator.GetAPIKeys(r)
case operator.GetAPIKey:
return b.authenticator.GetAPIKey(r)
case operator.GetMfaTokens:
return b.authenticator.GetMfaTokens(r)
case operator.GetMfaToken:
Expand Down

0 comments on commit 86bec33

Please sign in to comment.