Skip to content

Commit

Permalink
Feature: Add NRF Consumer support OAuth2 (#18)
Browse files Browse the repository at this point in the history
* Feature: NRF consumer support oauth2

* Add nrfCerPem config

* Fix: add minor changes

* Fix: prevent assertion and modify config setting

* Fix: move GetTokenCtx() and remove unsed condition

---------

Co-authored-by: CTFang@WireLab <ctfang.cs12@nycu.edu.tw>
  • Loading branch information
andy89923 and andy89923 authored Dec 18, 2023
1 parent e2fb235 commit 4d40628
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 19 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/antihax/optional v1.0.0
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/cydev/zero v0.0.0-20160322155811-4a4535dd56e7
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.9.1
Expand Down Expand Up @@ -57,7 +57,7 @@ require (
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
Expand Down
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs=
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI=
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6 h1:8P/wOkTAQMgZJe9pUUNSTE5PWeAdlMrsU9kLsI+VAVE=
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6/go.mod h1:qv9KqEucoZSeENPRFGxfTe+33ZWYyiYFx1Rj+H0DoWA=
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 h1:tNylIqH/m5Kq+3KuC+jjXGl06Y6EmM8yq61ZUgNrPBY=
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94/go.mod h1:aMszJZbCkcg5xaGgzya+55jz+OPMsJqPLq5Z3fWDFPE=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
Expand Down Expand Up @@ -330,7 +330,6 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
Expand All @@ -350,7 +349,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -552,6 +550,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
16 changes: 16 additions & 0 deletions internal/context/context.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package context

import (
"context"
"fmt"
"math"
"os"
Expand All @@ -12,6 +13,7 @@ import (

"github.com/free5gc/openapi"
"github.com/free5gc/openapi/models"
"github.com/free5gc/openapi/oauth"
"github.com/free5gc/pcf/internal/logger"
"github.com/free5gc/pcf/pkg/factory"
"github.com/free5gc/util/idgenerator"
Expand All @@ -31,6 +33,7 @@ type PCFContext struct {
PcfServiceUris map[models.ServiceName]string
PcfSuppFeats map[models.ServiceName]openapi.SupportedFeature
NrfUri string
NrfCertPem string
DefaultUdrURI string
Locality string
// UePool map[string]*UeContext
Expand All @@ -45,6 +48,8 @@ type PCFContext struct {

// lock
DefaultUdrURILock sync.RWMutex

OAuth2Required bool
}

type AMFStatusSubscriptionData struct {
Expand Down Expand Up @@ -86,6 +91,7 @@ func InitpcfContext(context *PCFContext) {

sbi := configuration.Sbi
context.NrfUri = configuration.NrfUri
context.NrfCertPem = configuration.NrfCertPem
context.UriScheme = ""
context.RegisterIPv4 = factory.PcfSbiDefaultIPv4 // default localhost
context.SBIPort = factory.PcfSbiDefaultPort // default port
Expand Down Expand Up @@ -426,3 +432,13 @@ func DeleteIpv6index(Ipv6index int32) {
func (c *PCFContext) NewAmfStatusSubscription(subscriptionID string, subscriptionData AMFStatusSubscriptionData) {
c.AMFStatusSubsData.Store(subscriptionID, subscriptionData)
}

func (c *PCFContext) GetTokenCtx(scope, targetNF string) (
context.Context, *models.ProblemDetails, error,
) {
if !c.OAuth2Required {
return context.TODO(), nil, nil
}
return oauth.GetTokenCtx(models.NfType_PCF,
c.NfId, c.NrfUri, scope, targetNF)
}
2 changes: 1 addition & 1 deletion internal/sbi/consumer/communication.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func AmfStatusChangeSubscribe(amfUri string, guamiList []models.Guami) (
} else if httpResp != nil {
if httpResp.Status != localErr.Error() {
err = localErr
return
return nil, err
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
Expand Down
6 changes: 3 additions & 3 deletions internal/sbi/consumer/influenceDataSubscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.S
ApplicationDataInfluenceDataSubsToNotifyPost(context.Background(), trafficInfluSub)
if localErr == nil {
locationHeader := httpResp.Header.Get("Location")
subscriptionID := locationHeader[strings.LastIndex(locationHeader, "/")+1:]
subscriptionID = locationHeader[strings.LastIndex(locationHeader, "/")+1:]
logger.ConsumerLog.Debugf("Influence Data Subscription ID: %s", subscriptionID)
return subscriptionID, nil, nil
} else if httpResp != nil {
Expand All @@ -38,7 +38,7 @@ func CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.S
}()
if httpResp.Status != localErr.Error() {
err = localErr
return
return subscriptionID, problemDetails, err
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
Expand Down Expand Up @@ -85,7 +85,7 @@ func RemoveInfluenceDataSubscription(ue *pcf_context.UeContext, subscriptionID s
}()
if httpResp.Status != localErr.Error() {
err = localErr
return
return nil, err
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
Expand Down
9 changes: 7 additions & 2 deletions internal/sbi/consumer/nf_discovery.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package consumer

import (
"context"
"fmt"
"net/http"

"github.com/antihax/optional"

"github.com/free5gc/openapi/Nnrf_NFDiscovery"
"github.com/free5gc/openapi/models"
pcf_context "github.com/free5gc/pcf/internal/context"
"github.com/free5gc/pcf/internal/logger"
"github.com/free5gc/pcf/internal/util"
)
Expand All @@ -22,7 +22,12 @@ func SendSearchNFInstances(
configuration.SetBasePath(nrfUri)
client := Nnrf_NFDiscovery.NewAPIClient(configuration)

result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, &param)
ctx, _, err := pcf_context.GetSelf().GetTokenCtx("nnrf-disc", "NRF")
if err != nil {
return nil, err
}

result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, &param)
if err != nil {
logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err)
}
Expand Down
30 changes: 25 additions & 5 deletions internal/sbi/consumer/nf_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
client := Nnrf_NFManagement.NewAPIClient(configuration)

var res *http.Response
var nf models.NfProfile
for {
_, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
if err != nil || res == nil {
// TODO : add log
fmt.Println(fmt.Errorf("PCF register to NRF Error[%v]", err.Error()))
Expand All @@ -76,6 +77,20 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
resourceUri := res.Header.Get("Location")
resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")]
retrieveNfInstanceID = resourceUri[strings.LastIndex(resourceUri, "/")+1:]

oauth2 := false
if nf.CustomInfo != nil {
v, ok := nf.CustomInfo["oauth2"].(bool)
if ok {
oauth2 = v
logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2)
}
}
pcf_context.GetSelf().OAuth2Required = oauth2

if oauth2 && pcf_context.GetSelf().NrfCertPem == "" {
logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.")
}
break
} else {
fmt.Println("NRF return wrong status code", status)
Expand All @@ -87,6 +102,11 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Infof("Send Deregister NFInstance")

ctx, pd, err := pcf_context.GetSelf().GetTokenCtx("nnrf-nfm", "NRF")
if err != nil {
return pd, err
}

pcfSelf := pcf_context.GetSelf()
// Set client and set url
configuration := Nnrf_NFManagement.NewConfiguration()
Expand All @@ -95,22 +115,22 @@ func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err erro

var res *http.Response

res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(context.Background(), pcfSelf.NfId)
res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, pcfSelf.NfId)
if err == nil {
return
return nil, nil
} else if res != nil {
defer func() {
if resCloseErr := res.Body.Close(); resCloseErr != nil {
logger.ConsumerLog.Errorf("DeregisterNFInstance response cannot close: %+v", resCloseErr)
}
}()
if res.Status != err.Error() {
return
return nil, err
}
problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
} else {
err = openapi.ReportError("server no response")
}
return
return problemDetails, err
}
2 changes: 1 addition & 1 deletion internal/sbi/producer/policyauthorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,7 @@ func updateQosInMedSubComp(qosData *models.QosData, comp *models.MediaComponent,
if comp.FStatus == models.FlowStatus_REMOVED {
updatedQosData.MaxbrDl = ""
updatedQosData.MaxbrUl = ""
return
return updatedQosData, ulExist, dlExist
}
maxBwUl := 0.0
maxBwDl := 0.0
Expand Down
2 changes: 1 addition & 1 deletion internal/util/pcc_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ func isUpPathChgEventExist(trafficInfluData *models.TrafficInfluData) bool {
trafficInfluData.DnaiChgType != ""
}

// subclause 4.2.6.2.6.2 in 3GPP TS 29.512.
// subclause 4.2.6.2.6.2 in 3GPP TS 29.512.
func setUpPathChgEvent(trafficInfluData *models.TrafficInfluData) *models.UpPathChgEvent {
return &models.UpPathChgEvent{
NotificationUri: trafficInfluData.UpPathChgNotifUri,
Expand Down
1 change: 1 addition & 0 deletions pkg/factory/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Configuration struct {
TimeFormat string `yaml:"timeFormat,omitempty" valid:"required"`
DefaultBdtRefId string `yaml:"defaultBdtRefId,omitempty" valid:"required, type(string)"`
NrfUri string `yaml:"nrfUri,omitempty" valid:"required, url"`
NrfCertPem string `yaml:"nrfCertPem,omitempty" valid:"optional"`
ServiceList []Service `yaml:"serviceList,omitempty" valid:"required"`
Mongodb *Mongodb `yaml:"mongodb" valid:"required"`
Locality string `yaml:"locality,omitempty" valid:"-"`
Expand Down

0 comments on commit 4d40628

Please sign in to comment.