Beispiel #1
0
// SignOut destroys the current session so that it cannot be used again
func (s *realScope) SignOut(user *User) error {
	cl := multiclient.New().DefaultScopeFrom(s.getRpcScope())

	cl.AddScopedReq(&multiclient.ScopedReq{
		Uid:      "deletesess",
		Service:  loginService,
		Endpoint: deleteSessionEndpoint,
		Req: &sessdelproto.Request{
			SessId: proto.String(user.SessId),
		},
		Rsp: &sessdelproto.Response{},
	})

	if cl.Execute().AnyErrors() {
		return cl.Succeeded("deletesess")
	}

	if err := s.userCache.Purge(user.SessId); err != nil {
		log.Errorf("[Auth] Error purging session cache: %v", err)
	}

	s.Lock()
	defer s.Unlock()

	s.authUser = nil
	s.triedAuth = false

	return nil
}
Beispiel #2
0
func (s *realScope) doAuth(mech, device string, creds map[string]string) (*User, error) {
	reqProto := &authproto.Request{
		Mech:       proto.String(mech),
		DeviceType: proto.String(device),
		Meta:       make([]*loginproto.KeyValue, 0),
	}
	for k, v := range creds {
		switch k {
		case "username":
			reqProto.Username = proto.String(v)
		case "password":
			reqProto.Password = proto.String(v)
		case "newPassword":
			reqProto.NewPassword = proto.String(v)
		case "application":
			reqProto.Application = proto.String(v)
		default:
			// Add additional fields to Meta, such as DeviceId, osVersion, appVersion
			reqProto.Meta = append(reqProto.Meta, &loginproto.KeyValue{
				Key:   proto.String(k),
				Value: proto.String(v),
			})
		}
	}

	cl := multiclient.New().DefaultScopeFrom(s.getRpcScope())
	rsp := &authproto.Response{}
	cl.AddScopedReq(&multiclient.ScopedReq{
		Uid:      "auth",
		Service:  loginService,
		Endpoint: authEndpoint,
		Req:      reqProto,
		Rsp:      rsp,
		Options:  client.Options{"retries": 0},
	})

	if cl.Execute().AnyErrors() {
		// specfically map out bad credentials error
		err := cl.Succeeded("auth")
		if err.Code() == badCredentialsErrCode {
			return nil, BadCredentialsError
		}
		return nil, err
	}

	// recover this user
	u, err := FromSessionToken(rsp.GetSessId(), rsp.GetToken())
	if err != nil {
		return nil, err
	}

	if err := s.userCache.Store(u); err != nil {
		log.Errorf("[Auth] Error caching session: %v", err)
	}

	return u, nil
}
Beispiel #3
0
// doRecoverSession is the meat and veg for RecoverSession
func (s *realScope) doRecoverSession(sessId string) (*User, error) {
	// Check cache; ignore errors (will have impact on service performance, but not functionality)
	queryLogin := false
	u, hit, err := s.userCache.Fetch(sessId)
	if err != nil {
		log.Warnf("[Auth] Error fetching session from cache (will call login service): %v", err)
		queryLogin = true
	} else if u != nil && u.ExpiryTs.Before(time.Now()) && u.CanAutoRenew() { // Cached token has expired
		log.Infof("[Auth] Cache-recovered token has expired (%s); will call login service", u.ExpiryTs.String())
		queryLogin = true
	} else {
		queryLogin = u == nil && !hit
	}

	if queryLogin {
		cl := multiclient.New().DefaultScopeFrom(s.getRpcScope())
		rsp := &sessreadproto.Response{}
		cl.AddScopedReq(&multiclient.ScopedReq{
			Uid:      "readsess",
			Service:  loginService,
			Endpoint: readSessionEndpoint,
			Req: &sessreadproto.Request{
				SessId: proto.String(sessId),
			},
			Rsp: rsp,
		})

		if cl.Execute().AnyErrorsIgnoring([]string{errors.ErrorNotFound}, nil) {
			err := cl.Succeeded("readsess")
			log.Errorf("[Auth] Auth scope recovery error [%s: %s] %v", err.Type(), err.Code(), err.Description())
			return nil, err
		}

		// found a session?
		if rsp.GetSessId() == "" && rsp.GetToken() == "" {
			log.Debugf("[Auth] Session '%s' not found (not valid) when trying to recover from login service", sessId)
			// @todo we could cache this (at least for a short time) to prevent repeated hammering of login service
		} else {
			u, err = FromSessionToken(rsp.GetSessId(), rsp.GetToken())
			if err != nil {
				log.Errorf("[Auth] Error getting user from session: %v", err)
			} else {
				log.Tracef("[Auth] Auth scope - recovered user '%s' from session '%s'", u.Id, rsp.GetSessId())
			}
		}

		// ignore errors; just means we have no user
		if u != nil {
			s.userCache.Store(u)
		}
	}

	return u, nil
}
Beispiel #4
0
// Call a service. No scoping/tracing yet.
func Call(service, endpoint string, request, response proto.Message) error {
	call := multiclient.New().DefaultScopeFrom(server.Scoper()).AddScopedReq(&multiclient.ScopedReq{
		Uid:      "dummy",
		Service:  service,
		Endpoint: endpoint,
		Req:      request,
		Rsp:      response,
	}).Execute()
	if call.AnyErrors() {
		return call.Succeeded("dummy")
	}
	return nil
}