github.com/cs3org/reva/v2@v2.27.7/pkg/sdk/session.go (about) 1 // Copyright 2018-2021 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package sdk 20 21 import ( 22 "context" 23 "crypto/tls" 24 "fmt" 25 "io" 26 27 registry "github.com/cs3org/go-cs3apis/cs3/auth/registry/v1beta1" 28 gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" 29 "google.golang.org/grpc" 30 "google.golang.org/grpc/credentials" 31 "google.golang.org/grpc/credentials/insecure" 32 "google.golang.org/grpc/metadata" 33 34 "github.com/cs3org/reva/v2/pkg/sdk/common" 35 "github.com/cs3org/reva/v2/pkg/sdk/common/net" 36 ) 37 38 // Session stores information about a Reva session. 39 // It is also responsible for managing the Reva gateway client. 40 type Session struct { 41 ctx context.Context 42 client gateway.GatewayAPIClient 43 44 token string 45 } 46 47 func (session *Session) initSession(ctx context.Context) error { 48 session.ctx = ctx 49 50 return nil 51 } 52 53 // Initiate initiates the session by creating a connection to the host and preparing the gateway client. 54 func (session *Session) Initiate(host string, insecure bool) error { 55 conn, err := session.getConnection(host, insecure) 56 if err != nil { 57 return fmt.Errorf("unable to establish a gRPC connection to '%v': %v", host, err) 58 } 59 session.client = gateway.NewGatewayAPIClient(conn) 60 61 return nil 62 } 63 64 func (session *Session) getConnection(host string, ins bool) (*grpc.ClientConn, error) { 65 if ins { 66 return grpc.NewClient(host, grpc.WithTransportCredentials(insecure.NewCredentials())) 67 } 68 69 tlsconf := &tls.Config{InsecureSkipVerify: false} 70 creds := credentials.NewTLS(tlsconf) 71 return grpc.NewClient(host, grpc.WithTransportCredentials(creds)) 72 } 73 74 // GetLoginMethods returns a list of all available login methods supported by the Reva instance. 75 func (session *Session) GetLoginMethods() ([]string, error) { 76 req := ®istry.ListAuthProvidersRequest{} 77 res, err := session.client.ListAuthProviders(session.ctx, req) 78 if err := net.CheckRPCInvocation("listing authorization providers", res, err); err != nil { 79 return []string{}, err 80 } 81 82 return res.Types, nil 83 } 84 85 // Login logs into Reva using the specified method and user credentials. 86 func (session *Session) Login(method string, username string, password string) error { 87 req := &gateway.AuthenticateRequest{ 88 Type: method, 89 ClientId: username, 90 ClientSecret: password, 91 } 92 res, err := session.client.Authenticate(session.ctx, req) 93 if err := net.CheckRPCInvocation("authenticating", res, err); err != nil { 94 return err 95 } 96 97 if res.Token == "" { 98 return fmt.Errorf("invalid token received: %q", res.Token) 99 } 100 session.token = res.Token 101 102 // Now that we have a valid token, we can append this to our context 103 session.ctx = context.WithValue(session.ctx, net.AccessTokenIndex, session.token) 104 session.ctx = metadata.AppendToOutgoingContext(session.ctx, net.AccessTokenName, session.token) 105 106 return nil 107 } 108 109 // BasicLogin tries to log into Reva using basic authentication. 110 // Before the actual login attempt, the method verifies that the Reva instance does support the "basic" login method. 111 func (session *Session) BasicLogin(username string, password string) error { 112 // Check if the 'basic' method is actually supported by the Reva instance; only continue if this is the case 113 supportedMethods, err := session.GetLoginMethods() 114 if err != nil { 115 return fmt.Errorf("unable to get a list of all supported login methods: %v", err) 116 } 117 118 if common.FindStringNoCase(supportedMethods, "basic") == -1 { 119 return fmt.Errorf("'basic' login method is not supported") 120 } 121 122 return session.Login("basic", username, password) 123 } 124 125 // NewHTTPRequest returns an HTTP request instance. 126 func (session *Session) NewHTTPRequest(endpoint string, method string, transportToken string, data io.Reader) (*net.HTTPRequest, error) { 127 return net.NewHTTPRequest(session.ctx, endpoint, method, session.token, transportToken, data) 128 } 129 130 // Client gets the gateway client instance. 131 func (session *Session) Client() gateway.GatewayAPIClient { 132 return session.client 133 } 134 135 // Context returns the session context. 136 func (session *Session) Context() context.Context { 137 return session.ctx 138 } 139 140 // Token returns the session token. 141 func (session *Session) Token() string { 142 return session.token 143 } 144 145 // IsValid checks whether the session has been initialized and fully established. 146 func (session *Session) IsValid() bool { 147 return session.client != nil && session.ctx != nil && session.token != "" 148 } 149 150 // NewSessionWithContext creates a new Reva session using the provided context. 151 func NewSessionWithContext(ctx context.Context) (*Session, error) { 152 session := &Session{} 153 if err := session.initSession(ctx); err != nil { 154 return nil, fmt.Errorf("unable to initialize the session: %v", err) 155 } 156 return session, nil 157 } 158 159 // NewSession creates a new Reva session using a default background context. 160 func NewSession() (*Session, error) { 161 return NewSessionWithContext(context.Background()) 162 } 163 164 // MustNewSession creates a new session and panics on failure. 165 func MustNewSession() *Session { 166 session, err := NewSession() 167 if err != nil { 168 panic(err) 169 } 170 return session 171 }