Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
b6d46fd5
Unverified
Commit
b6d46fd5
authored
Mar 27, 2026
by
InCerryGit
Committed by
GitHub
Mar 27, 2026
Browse files
Merge branch 'Wei-Shaw:main' into main
parents
fa68cbad
fdd8499f
Changes
107
Hide whitespace changes
Inline
Side-by-side
backend/ent/tlsfingerprintprofile_update.go
0 → 100644
View file @
b6d46fd5
// Code generated by ent, DO NOT EDIT.
package
ent
import
(
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/dialect/sql/sqljson"
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/tlsfingerprintprofile"
)
// TLSFingerprintProfileUpdate is the builder for updating TLSFingerprintProfile entities.
type
TLSFingerprintProfileUpdate
struct
{
config
hooks
[]
Hook
mutation
*
TLSFingerprintProfileMutation
}
// Where appends a list predicates to the TLSFingerprintProfileUpdate builder.
func
(
_u
*
TLSFingerprintProfileUpdate
)
Where
(
ps
...
predicate
.
TLSFingerprintProfile
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
Where
(
ps
...
)
return
_u
}
// SetUpdatedAt sets the "updated_at" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetUpdatedAt
(
v
time
.
Time
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetUpdatedAt
(
v
)
return
_u
}
// SetName sets the "name" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetName
(
v
string
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetName
(
v
)
return
_u
}
// SetNillableName sets the "name" field if the given value is not nil.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetNillableName
(
v
*
string
)
*
TLSFingerprintProfileUpdate
{
if
v
!=
nil
{
_u
.
SetName
(
*
v
)
}
return
_u
}
// SetDescription sets the "description" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetDescription
(
v
string
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetDescription
(
v
)
return
_u
}
// SetNillableDescription sets the "description" field if the given value is not nil.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetNillableDescription
(
v
*
string
)
*
TLSFingerprintProfileUpdate
{
if
v
!=
nil
{
_u
.
SetDescription
(
*
v
)
}
return
_u
}
// ClearDescription clears the value of the "description" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearDescription
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearDescription
()
return
_u
}
// SetEnableGrease sets the "enable_grease" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetEnableGrease
(
v
bool
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetEnableGrease
(
v
)
return
_u
}
// SetNillableEnableGrease sets the "enable_grease" field if the given value is not nil.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetNillableEnableGrease
(
v
*
bool
)
*
TLSFingerprintProfileUpdate
{
if
v
!=
nil
{
_u
.
SetEnableGrease
(
*
v
)
}
return
_u
}
// SetCipherSuites sets the "cipher_suites" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetCipherSuites
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetCipherSuites
(
v
)
return
_u
}
// AppendCipherSuites appends value to the "cipher_suites" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendCipherSuites
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendCipherSuites
(
v
)
return
_u
}
// ClearCipherSuites clears the value of the "cipher_suites" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearCipherSuites
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearCipherSuites
()
return
_u
}
// SetCurves sets the "curves" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetCurves
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetCurves
(
v
)
return
_u
}
// AppendCurves appends value to the "curves" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendCurves
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendCurves
(
v
)
return
_u
}
// ClearCurves clears the value of the "curves" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearCurves
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearCurves
()
return
_u
}
// SetPointFormats sets the "point_formats" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetPointFormats
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetPointFormats
(
v
)
return
_u
}
// AppendPointFormats appends value to the "point_formats" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendPointFormats
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendPointFormats
(
v
)
return
_u
}
// ClearPointFormats clears the value of the "point_formats" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearPointFormats
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearPointFormats
()
return
_u
}
// SetSignatureAlgorithms sets the "signature_algorithms" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetSignatureAlgorithms
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetSignatureAlgorithms
(
v
)
return
_u
}
// AppendSignatureAlgorithms appends value to the "signature_algorithms" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendSignatureAlgorithms
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendSignatureAlgorithms
(
v
)
return
_u
}
// ClearSignatureAlgorithms clears the value of the "signature_algorithms" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearSignatureAlgorithms
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearSignatureAlgorithms
()
return
_u
}
// SetAlpnProtocols sets the "alpn_protocols" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetAlpnProtocols
(
v
[]
string
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetAlpnProtocols
(
v
)
return
_u
}
// AppendAlpnProtocols appends value to the "alpn_protocols" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendAlpnProtocols
(
v
[]
string
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendAlpnProtocols
(
v
)
return
_u
}
// ClearAlpnProtocols clears the value of the "alpn_protocols" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearAlpnProtocols
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearAlpnProtocols
()
return
_u
}
// SetSupportedVersions sets the "supported_versions" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetSupportedVersions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetSupportedVersions
(
v
)
return
_u
}
// AppendSupportedVersions appends value to the "supported_versions" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendSupportedVersions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendSupportedVersions
(
v
)
return
_u
}
// ClearSupportedVersions clears the value of the "supported_versions" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearSupportedVersions
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearSupportedVersions
()
return
_u
}
// SetKeyShareGroups sets the "key_share_groups" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetKeyShareGroups
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetKeyShareGroups
(
v
)
return
_u
}
// AppendKeyShareGroups appends value to the "key_share_groups" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendKeyShareGroups
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendKeyShareGroups
(
v
)
return
_u
}
// ClearKeyShareGroups clears the value of the "key_share_groups" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearKeyShareGroups
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearKeyShareGroups
()
return
_u
}
// SetPskModes sets the "psk_modes" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetPskModes
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetPskModes
(
v
)
return
_u
}
// AppendPskModes appends value to the "psk_modes" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendPskModes
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendPskModes
(
v
)
return
_u
}
// ClearPskModes clears the value of the "psk_modes" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearPskModes
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearPskModes
()
return
_u
}
// SetExtensions sets the "extensions" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SetExtensions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
SetExtensions
(
v
)
return
_u
}
// AppendExtensions appends value to the "extensions" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
AppendExtensions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
AppendExtensions
(
v
)
return
_u
}
// ClearExtensions clears the value of the "extensions" field.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ClearExtensions
()
*
TLSFingerprintProfileUpdate
{
_u
.
mutation
.
ClearExtensions
()
return
_u
}
// Mutation returns the TLSFingerprintProfileMutation object of the builder.
func
(
_u
*
TLSFingerprintProfileUpdate
)
Mutation
()
*
TLSFingerprintProfileMutation
{
return
_u
.
mutation
}
// Save executes the query and returns the number of nodes affected by the update operation.
func
(
_u
*
TLSFingerprintProfileUpdate
)
Save
(
ctx
context
.
Context
)
(
int
,
error
)
{
_u
.
defaults
()
return
withHooks
(
ctx
,
_u
.
sqlSave
,
_u
.
mutation
,
_u
.
hooks
)
}
// SaveX is like Save, but panics if an error occurs.
func
(
_u
*
TLSFingerprintProfileUpdate
)
SaveX
(
ctx
context
.
Context
)
int
{
affected
,
err
:=
_u
.
Save
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
affected
}
// Exec executes the query.
func
(
_u
*
TLSFingerprintProfileUpdate
)
Exec
(
ctx
context
.
Context
)
error
{
_
,
err
:=
_u
.
Save
(
ctx
)
return
err
}
// ExecX is like Exec, but panics if an error occurs.
func
(
_u
*
TLSFingerprintProfileUpdate
)
ExecX
(
ctx
context
.
Context
)
{
if
err
:=
_u
.
Exec
(
ctx
);
err
!=
nil
{
panic
(
err
)
}
}
// defaults sets the default values of the builder before save.
func
(
_u
*
TLSFingerprintProfileUpdate
)
defaults
()
{
if
_
,
ok
:=
_u
.
mutation
.
UpdatedAt
();
!
ok
{
v
:=
tlsfingerprintprofile
.
UpdateDefaultUpdatedAt
()
_u
.
mutation
.
SetUpdatedAt
(
v
)
}
}
// check runs all checks and user-defined validators on the builder.
func
(
_u
*
TLSFingerprintProfileUpdate
)
check
()
error
{
if
v
,
ok
:=
_u
.
mutation
.
Name
();
ok
{
if
err
:=
tlsfingerprintprofile
.
NameValidator
(
v
);
err
!=
nil
{
return
&
ValidationError
{
Name
:
"name"
,
err
:
fmt
.
Errorf
(
`ent: validator failed for field "TLSFingerprintProfile.name": %w`
,
err
)}
}
}
return
nil
}
func
(
_u
*
TLSFingerprintProfileUpdate
)
sqlSave
(
ctx
context
.
Context
)
(
_node
int
,
err
error
)
{
if
err
:=
_u
.
check
();
err
!=
nil
{
return
_node
,
err
}
_spec
:=
sqlgraph
.
NewUpdateSpec
(
tlsfingerprintprofile
.
Table
,
tlsfingerprintprofile
.
Columns
,
sqlgraph
.
NewFieldSpec
(
tlsfingerprintprofile
.
FieldID
,
field
.
TypeInt64
))
if
ps
:=
_u
.
mutation
.
predicates
;
len
(
ps
)
>
0
{
_spec
.
Predicate
=
func
(
selector
*
sql
.
Selector
)
{
for
i
:=
range
ps
{
ps
[
i
](
selector
)
}
}
}
if
value
,
ok
:=
_u
.
mutation
.
UpdatedAt
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldUpdatedAt
,
field
.
TypeTime
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Name
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldName
,
field
.
TypeString
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Description
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldDescription
,
field
.
TypeString
,
value
)
}
if
_u
.
mutation
.
DescriptionCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldDescription
,
field
.
TypeString
)
}
if
value
,
ok
:=
_u
.
mutation
.
EnableGrease
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldEnableGrease
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
CipherSuites
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldCipherSuites
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedCipherSuites
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldCipherSuites
,
value
)
})
}
if
_u
.
mutation
.
CipherSuitesCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldCipherSuites
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
Curves
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldCurves
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedCurves
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldCurves
,
value
)
})
}
if
_u
.
mutation
.
CurvesCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldCurves
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
PointFormats
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldPointFormats
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedPointFormats
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldPointFormats
,
value
)
})
}
if
_u
.
mutation
.
PointFormatsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldPointFormats
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
SignatureAlgorithms
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldSignatureAlgorithms
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedSignatureAlgorithms
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldSignatureAlgorithms
,
value
)
})
}
if
_u
.
mutation
.
SignatureAlgorithmsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldSignatureAlgorithms
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
AlpnProtocols
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldAlpnProtocols
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedAlpnProtocols
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldAlpnProtocols
,
value
)
})
}
if
_u
.
mutation
.
AlpnProtocolsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldAlpnProtocols
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
SupportedVersions
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldSupportedVersions
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedSupportedVersions
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldSupportedVersions
,
value
)
})
}
if
_u
.
mutation
.
SupportedVersionsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldSupportedVersions
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
KeyShareGroups
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldKeyShareGroups
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedKeyShareGroups
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldKeyShareGroups
,
value
)
})
}
if
_u
.
mutation
.
KeyShareGroupsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldKeyShareGroups
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
PskModes
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldPskModes
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedPskModes
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldPskModes
,
value
)
})
}
if
_u
.
mutation
.
PskModesCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldPskModes
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
Extensions
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldExtensions
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedExtensions
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldExtensions
,
value
)
})
}
if
_u
.
mutation
.
ExtensionsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldExtensions
,
field
.
TypeJSON
)
}
if
_node
,
err
=
sqlgraph
.
UpdateNodes
(
ctx
,
_u
.
driver
,
_spec
);
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
sqlgraph
.
NotFoundError
);
ok
{
err
=
&
NotFoundError
{
tlsfingerprintprofile
.
Label
}
}
else
if
sqlgraph
.
IsConstraintError
(
err
)
{
err
=
&
ConstraintError
{
msg
:
err
.
Error
(),
wrap
:
err
}
}
return
0
,
err
}
_u
.
mutation
.
done
=
true
return
_node
,
nil
}
// TLSFingerprintProfileUpdateOne is the builder for updating a single TLSFingerprintProfile entity.
type
TLSFingerprintProfileUpdateOne
struct
{
config
fields
[]
string
hooks
[]
Hook
mutation
*
TLSFingerprintProfileMutation
}
// SetUpdatedAt sets the "updated_at" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetUpdatedAt
(
v
time
.
Time
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetUpdatedAt
(
v
)
return
_u
}
// SetName sets the "name" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetName
(
v
string
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetName
(
v
)
return
_u
}
// SetNillableName sets the "name" field if the given value is not nil.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetNillableName
(
v
*
string
)
*
TLSFingerprintProfileUpdateOne
{
if
v
!=
nil
{
_u
.
SetName
(
*
v
)
}
return
_u
}
// SetDescription sets the "description" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetDescription
(
v
string
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetDescription
(
v
)
return
_u
}
// SetNillableDescription sets the "description" field if the given value is not nil.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetNillableDescription
(
v
*
string
)
*
TLSFingerprintProfileUpdateOne
{
if
v
!=
nil
{
_u
.
SetDescription
(
*
v
)
}
return
_u
}
// ClearDescription clears the value of the "description" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearDescription
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearDescription
()
return
_u
}
// SetEnableGrease sets the "enable_grease" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetEnableGrease
(
v
bool
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetEnableGrease
(
v
)
return
_u
}
// SetNillableEnableGrease sets the "enable_grease" field if the given value is not nil.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetNillableEnableGrease
(
v
*
bool
)
*
TLSFingerprintProfileUpdateOne
{
if
v
!=
nil
{
_u
.
SetEnableGrease
(
*
v
)
}
return
_u
}
// SetCipherSuites sets the "cipher_suites" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetCipherSuites
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetCipherSuites
(
v
)
return
_u
}
// AppendCipherSuites appends value to the "cipher_suites" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendCipherSuites
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendCipherSuites
(
v
)
return
_u
}
// ClearCipherSuites clears the value of the "cipher_suites" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearCipherSuites
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearCipherSuites
()
return
_u
}
// SetCurves sets the "curves" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetCurves
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetCurves
(
v
)
return
_u
}
// AppendCurves appends value to the "curves" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendCurves
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendCurves
(
v
)
return
_u
}
// ClearCurves clears the value of the "curves" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearCurves
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearCurves
()
return
_u
}
// SetPointFormats sets the "point_formats" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetPointFormats
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetPointFormats
(
v
)
return
_u
}
// AppendPointFormats appends value to the "point_formats" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendPointFormats
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendPointFormats
(
v
)
return
_u
}
// ClearPointFormats clears the value of the "point_formats" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearPointFormats
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearPointFormats
()
return
_u
}
// SetSignatureAlgorithms sets the "signature_algorithms" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetSignatureAlgorithms
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetSignatureAlgorithms
(
v
)
return
_u
}
// AppendSignatureAlgorithms appends value to the "signature_algorithms" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendSignatureAlgorithms
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendSignatureAlgorithms
(
v
)
return
_u
}
// ClearSignatureAlgorithms clears the value of the "signature_algorithms" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearSignatureAlgorithms
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearSignatureAlgorithms
()
return
_u
}
// SetAlpnProtocols sets the "alpn_protocols" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetAlpnProtocols
(
v
[]
string
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetAlpnProtocols
(
v
)
return
_u
}
// AppendAlpnProtocols appends value to the "alpn_protocols" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendAlpnProtocols
(
v
[]
string
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendAlpnProtocols
(
v
)
return
_u
}
// ClearAlpnProtocols clears the value of the "alpn_protocols" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearAlpnProtocols
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearAlpnProtocols
()
return
_u
}
// SetSupportedVersions sets the "supported_versions" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetSupportedVersions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetSupportedVersions
(
v
)
return
_u
}
// AppendSupportedVersions appends value to the "supported_versions" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendSupportedVersions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendSupportedVersions
(
v
)
return
_u
}
// ClearSupportedVersions clears the value of the "supported_versions" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearSupportedVersions
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearSupportedVersions
()
return
_u
}
// SetKeyShareGroups sets the "key_share_groups" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetKeyShareGroups
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetKeyShareGroups
(
v
)
return
_u
}
// AppendKeyShareGroups appends value to the "key_share_groups" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendKeyShareGroups
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendKeyShareGroups
(
v
)
return
_u
}
// ClearKeyShareGroups clears the value of the "key_share_groups" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearKeyShareGroups
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearKeyShareGroups
()
return
_u
}
// SetPskModes sets the "psk_modes" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetPskModes
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetPskModes
(
v
)
return
_u
}
// AppendPskModes appends value to the "psk_modes" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendPskModes
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendPskModes
(
v
)
return
_u
}
// ClearPskModes clears the value of the "psk_modes" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearPskModes
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearPskModes
()
return
_u
}
// SetExtensions sets the "extensions" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SetExtensions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
SetExtensions
(
v
)
return
_u
}
// AppendExtensions appends value to the "extensions" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
AppendExtensions
(
v
[]
uint16
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
AppendExtensions
(
v
)
return
_u
}
// ClearExtensions clears the value of the "extensions" field.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ClearExtensions
()
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
ClearExtensions
()
return
_u
}
// Mutation returns the TLSFingerprintProfileMutation object of the builder.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
Mutation
()
*
TLSFingerprintProfileMutation
{
return
_u
.
mutation
}
// Where appends a list predicates to the TLSFingerprintProfileUpdate builder.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
Where
(
ps
...
predicate
.
TLSFingerprintProfile
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
mutation
.
Where
(
ps
...
)
return
_u
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
Select
(
field
string
,
fields
...
string
)
*
TLSFingerprintProfileUpdateOne
{
_u
.
fields
=
append
([]
string
{
field
},
fields
...
)
return
_u
}
// Save executes the query and returns the updated TLSFingerprintProfile entity.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
Save
(
ctx
context
.
Context
)
(
*
TLSFingerprintProfile
,
error
)
{
_u
.
defaults
()
return
withHooks
(
ctx
,
_u
.
sqlSave
,
_u
.
mutation
,
_u
.
hooks
)
}
// SaveX is like Save, but panics if an error occurs.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
SaveX
(
ctx
context
.
Context
)
*
TLSFingerprintProfile
{
node
,
err
:=
_u
.
Save
(
ctx
)
if
err
!=
nil
{
panic
(
err
)
}
return
node
}
// Exec executes the query on the entity.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
Exec
(
ctx
context
.
Context
)
error
{
_
,
err
:=
_u
.
Save
(
ctx
)
return
err
}
// ExecX is like Exec, but panics if an error occurs.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
ExecX
(
ctx
context
.
Context
)
{
if
err
:=
_u
.
Exec
(
ctx
);
err
!=
nil
{
panic
(
err
)
}
}
// defaults sets the default values of the builder before save.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
defaults
()
{
if
_
,
ok
:=
_u
.
mutation
.
UpdatedAt
();
!
ok
{
v
:=
tlsfingerprintprofile
.
UpdateDefaultUpdatedAt
()
_u
.
mutation
.
SetUpdatedAt
(
v
)
}
}
// check runs all checks and user-defined validators on the builder.
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
check
()
error
{
if
v
,
ok
:=
_u
.
mutation
.
Name
();
ok
{
if
err
:=
tlsfingerprintprofile
.
NameValidator
(
v
);
err
!=
nil
{
return
&
ValidationError
{
Name
:
"name"
,
err
:
fmt
.
Errorf
(
`ent: validator failed for field "TLSFingerprintProfile.name": %w`
,
err
)}
}
}
return
nil
}
func
(
_u
*
TLSFingerprintProfileUpdateOne
)
sqlSave
(
ctx
context
.
Context
)
(
_node
*
TLSFingerprintProfile
,
err
error
)
{
if
err
:=
_u
.
check
();
err
!=
nil
{
return
_node
,
err
}
_spec
:=
sqlgraph
.
NewUpdateSpec
(
tlsfingerprintprofile
.
Table
,
tlsfingerprintprofile
.
Columns
,
sqlgraph
.
NewFieldSpec
(
tlsfingerprintprofile
.
FieldID
,
field
.
TypeInt64
))
id
,
ok
:=
_u
.
mutation
.
ID
()
if
!
ok
{
return
nil
,
&
ValidationError
{
Name
:
"id"
,
err
:
errors
.
New
(
`ent: missing "TLSFingerprintProfile.id" for update`
)}
}
_spec
.
Node
.
ID
.
Value
=
id
if
fields
:=
_u
.
fields
;
len
(
fields
)
>
0
{
_spec
.
Node
.
Columns
=
make
([]
string
,
0
,
len
(
fields
))
_spec
.
Node
.
Columns
=
append
(
_spec
.
Node
.
Columns
,
tlsfingerprintprofile
.
FieldID
)
for
_
,
f
:=
range
fields
{
if
!
tlsfingerprintprofile
.
ValidColumn
(
f
)
{
return
nil
,
&
ValidationError
{
Name
:
f
,
err
:
fmt
.
Errorf
(
"ent: invalid field %q for query"
,
f
)}
}
if
f
!=
tlsfingerprintprofile
.
FieldID
{
_spec
.
Node
.
Columns
=
append
(
_spec
.
Node
.
Columns
,
f
)
}
}
}
if
ps
:=
_u
.
mutation
.
predicates
;
len
(
ps
)
>
0
{
_spec
.
Predicate
=
func
(
selector
*
sql
.
Selector
)
{
for
i
:=
range
ps
{
ps
[
i
](
selector
)
}
}
}
if
value
,
ok
:=
_u
.
mutation
.
UpdatedAt
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldUpdatedAt
,
field
.
TypeTime
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Name
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldName
,
field
.
TypeString
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
Description
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldDescription
,
field
.
TypeString
,
value
)
}
if
_u
.
mutation
.
DescriptionCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldDescription
,
field
.
TypeString
)
}
if
value
,
ok
:=
_u
.
mutation
.
EnableGrease
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldEnableGrease
,
field
.
TypeBool
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
CipherSuites
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldCipherSuites
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedCipherSuites
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldCipherSuites
,
value
)
})
}
if
_u
.
mutation
.
CipherSuitesCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldCipherSuites
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
Curves
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldCurves
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedCurves
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldCurves
,
value
)
})
}
if
_u
.
mutation
.
CurvesCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldCurves
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
PointFormats
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldPointFormats
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedPointFormats
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldPointFormats
,
value
)
})
}
if
_u
.
mutation
.
PointFormatsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldPointFormats
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
SignatureAlgorithms
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldSignatureAlgorithms
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedSignatureAlgorithms
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldSignatureAlgorithms
,
value
)
})
}
if
_u
.
mutation
.
SignatureAlgorithmsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldSignatureAlgorithms
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
AlpnProtocols
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldAlpnProtocols
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedAlpnProtocols
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldAlpnProtocols
,
value
)
})
}
if
_u
.
mutation
.
AlpnProtocolsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldAlpnProtocols
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
SupportedVersions
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldSupportedVersions
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedSupportedVersions
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldSupportedVersions
,
value
)
})
}
if
_u
.
mutation
.
SupportedVersionsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldSupportedVersions
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
KeyShareGroups
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldKeyShareGroups
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedKeyShareGroups
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldKeyShareGroups
,
value
)
})
}
if
_u
.
mutation
.
KeyShareGroupsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldKeyShareGroups
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
PskModes
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldPskModes
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedPskModes
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldPskModes
,
value
)
})
}
if
_u
.
mutation
.
PskModesCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldPskModes
,
field
.
TypeJSON
)
}
if
value
,
ok
:=
_u
.
mutation
.
Extensions
();
ok
{
_spec
.
SetField
(
tlsfingerprintprofile
.
FieldExtensions
,
field
.
TypeJSON
,
value
)
}
if
value
,
ok
:=
_u
.
mutation
.
AppendedExtensions
();
ok
{
_spec
.
AddModifier
(
func
(
u
*
sql
.
UpdateBuilder
)
{
sqljson
.
Append
(
u
,
tlsfingerprintprofile
.
FieldExtensions
,
value
)
})
}
if
_u
.
mutation
.
ExtensionsCleared
()
{
_spec
.
ClearField
(
tlsfingerprintprofile
.
FieldExtensions
,
field
.
TypeJSON
)
}
_node
=
&
TLSFingerprintProfile
{
config
:
_u
.
config
}
_spec
.
Assign
=
_node
.
assignValues
_spec
.
ScanValues
=
_node
.
scanValues
if
err
=
sqlgraph
.
UpdateNode
(
ctx
,
_u
.
driver
,
_spec
);
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
sqlgraph
.
NotFoundError
);
ok
{
err
=
&
NotFoundError
{
tlsfingerprintprofile
.
Label
}
}
else
if
sqlgraph
.
IsConstraintError
(
err
)
{
err
=
&
ConstraintError
{
msg
:
err
.
Error
(),
wrap
:
err
}
}
return
nil
,
err
}
_u
.
mutation
.
done
=
true
return
_node
,
nil
}
backend/ent/tx.go
View file @
b6d46fd5
...
...
@@ -42,6 +42,8 @@ type Tx struct {
SecuritySecret
*
SecuritySecretClient
// Setting is the client for interacting with the Setting builders.
Setting
*
SettingClient
// TLSFingerprintProfile is the client for interacting with the TLSFingerprintProfile builders.
TLSFingerprintProfile
*
TLSFingerprintProfileClient
// UsageCleanupTask is the client for interacting with the UsageCleanupTask builders.
UsageCleanupTask
*
UsageCleanupTaskClient
// UsageLog is the client for interacting with the UsageLog builders.
...
...
@@ -201,6 +203,7 @@ func (tx *Tx) init() {
tx
.
RedeemCode
=
NewRedeemCodeClient
(
tx
.
config
)
tx
.
SecuritySecret
=
NewSecuritySecretClient
(
tx
.
config
)
tx
.
Setting
=
NewSettingClient
(
tx
.
config
)
tx
.
TLSFingerprintProfile
=
NewTLSFingerprintProfileClient
(
tx
.
config
)
tx
.
UsageCleanupTask
=
NewUsageCleanupTaskClient
(
tx
.
config
)
tx
.
UsageLog
=
NewUsageLogClient
(
tx
.
config
)
tx
.
User
=
NewUserClient
(
tx
.
config
)
...
...
backend/internal/config/config.go
View file @
b6d46fd5
...
...
@@ -656,17 +656,33 @@ type TLSFingerprintConfig struct {
}
// TLSProfileConfig 单个TLS指纹模板的配置
// 所有列表字段为空时使用内置默认值(Claude CLI 2.x / Node.js 20.x)
// 建议通过 TLS 指纹采集工具 (tests/tls-fingerprint-web) 获取完整配置
type
TLSProfileConfig
struct
{
// Name: 模板显示名称
Name
string
`mapstructure:"name"`
// EnableGREASE: 是否启用GREASE扩展(Chrome使用,Node.js不使用)
EnableGREASE
bool
`mapstructure:"enable_grease"`
// CipherSuites: TLS加密套件列表
(空则使用内置默认值)
// CipherSuites: TLS加密套件列表
CipherSuites
[]
uint16
`mapstructure:"cipher_suites"`
// Curves: 椭圆曲线列表
(空则使用内置默认值)
// Curves: 椭圆曲线列表
Curves
[]
uint16
`mapstructure:"curves"`
// PointFormats: 点格式列表(空则使用内置默认值)
PointFormats
[]
uint8
`mapstructure:"point_formats"`
// PointFormats: 点格式列表
PointFormats
[]
uint16
`mapstructure:"point_formats"`
// SignatureAlgorithms: 签名算法列表
SignatureAlgorithms
[]
uint16
`mapstructure:"signature_algorithms"`
// ALPNProtocols: ALPN协议列表(如 ["h2", "http/1.1"])
ALPNProtocols
[]
string
`mapstructure:"alpn_protocols"`
// SupportedVersions: 支持的TLS版本列表(如 [0x0304, 0x0303] 即 TLS1.3, TLS1.2)
SupportedVersions
[]
uint16
`mapstructure:"supported_versions"`
// KeyShareGroups: Key Share中发送的曲线组(如 [29] 即 X25519)
KeyShareGroups
[]
uint16
`mapstructure:"key_share_groups"`
// PSKModes: PSK密钥交换模式(如 [1] 即 psk_dhe_ke)
PSKModes
[]
uint16
`mapstructure:"psk_modes"`
// Extensions: TLS扩展类型ID列表,按发送顺序排列
// 空则使用内置默认顺序 [0,11,10,35,16,22,23,13,43,45,51]
// GREASE值(如0x0a0a)会自动插入GREASE扩展
Extensions
[]
uint16
`mapstructure:"extensions"`
}
// GatewaySchedulingConfig accounts scheduling configuration.
...
...
backend/internal/handler/admin/account_data.go
View file @
b6d46fd5
...
...
@@ -267,6 +267,9 @@ func (h *AccountHandler) importData(ctx context.Context, req DataImportRequest)
}
}
// 收集需要异步设置隐私的 Antigravity OAuth 账号
var
privacyAccounts
[]
*
service
.
Account
for
i
:=
range
dataPayload
.
Accounts
{
item
:=
dataPayload
.
Accounts
[
i
]
if
err
:=
validateDataAccount
(
item
);
err
!=
nil
{
...
...
@@ -314,7 +317,8 @@ func (h *AccountHandler) importData(ctx context.Context, req DataImportRequest)
SkipDefaultGroupBind
:
skipDefaultGroupBind
,
}
if
_
,
err
:=
h
.
adminService
.
CreateAccount
(
ctx
,
accountInput
);
err
!=
nil
{
created
,
err
:=
h
.
adminService
.
CreateAccount
(
ctx
,
accountInput
)
if
err
!=
nil
{
result
.
AccountFailed
++
result
.
Errors
=
append
(
result
.
Errors
,
DataImportError
{
Kind
:
"account"
,
...
...
@@ -323,9 +327,30 @@ func (h *AccountHandler) importData(ctx context.Context, req DataImportRequest)
})
continue
}
// 收集 Antigravity OAuth 账号,稍后异步设置隐私
if
created
.
Platform
==
service
.
PlatformAntigravity
&&
created
.
Type
==
service
.
AccountTypeOAuth
{
privacyAccounts
=
append
(
privacyAccounts
,
created
)
}
result
.
AccountCreated
++
}
// 异步设置 Antigravity 隐私,避免大量导入时阻塞请求
if
len
(
privacyAccounts
)
>
0
{
adminSvc
:=
h
.
adminService
go
func
()
{
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
slog
.
Error
(
"import_antigravity_privacy_panic"
,
"recover"
,
r
)
}
}()
bgCtx
:=
context
.
Background
()
for
_
,
acc
:=
range
privacyAccounts
{
adminSvc
.
ForceAntigravityPrivacy
(
bgCtx
,
acc
)
}
slog
.
Info
(
"import_antigravity_privacy_done"
,
"count"
,
len
(
privacyAccounts
))
}()
}
return
result
,
nil
}
...
...
backend/internal/handler/admin/account_handler.go
View file @
b6d46fd5
...
...
@@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"log"
"log/slog"
"net/http"
"strconv"
"strings"
...
...
@@ -536,6 +537,10 @@ func (h *AccountHandler) Create(c *gin.Context) {
if
execErr
!=
nil
{
return
nil
,
execErr
}
// Antigravity OAuth: 新账号直接设置隐私
h
.
adminService
.
ForceAntigravityPrivacy
(
ctx
,
account
)
// OpenAI OAuth: 新账号直接设置隐私
h
.
adminService
.
ForceOpenAIPrivacy
(
ctx
,
account
)
return
h
.
buildAccountResponseWithRuntime
(
ctx
,
account
),
nil
})
if
err
!=
nil
{
...
...
@@ -782,6 +787,8 @@ func (h *AccountHandler) refreshSingleAccount(ctx context.Context, account *serv
if
account
.
IsOpenAI
()
{
tokenInfo
,
err
:=
h
.
openaiOAuthService
.
RefreshAccountToken
(
ctx
,
account
)
if
err
!=
nil
{
// 刷新失败但 access_token 可能仍有效,尝试设置隐私
h
.
adminService
.
EnsureOpenAIPrivacy
(
ctx
,
account
)
return
nil
,
""
,
err
}
...
...
@@ -883,6 +890,8 @@ func (h *AccountHandler) refreshSingleAccount(ctx context.Context, account *serv
// OpenAI OAuth: 刷新成功后检查并设置 privacy_mode
h
.
adminService
.
EnsureOpenAIPrivacy
(
ctx
,
updatedAccount
)
// Antigravity OAuth: 刷新成功后检查并设置 privacy_mode
h
.
adminService
.
EnsureAntigravityPrivacy
(
ctx
,
updatedAccount
)
return
updatedAccount
,
""
,
nil
}
...
...
@@ -1154,6 +1163,9 @@ func (h *AccountHandler) BatchCreate(c *gin.Context) {
success
:=
0
failed
:=
0
results
:=
make
([]
gin
.
H
,
0
,
len
(
req
.
Accounts
))
// 收集需要异步设置隐私的 OAuth 账号
var
antigravityPrivacyAccounts
[]
*
service
.
Account
var
openaiPrivacyAccounts
[]
*
service
.
Account
for
_
,
item
:=
range
req
.
Accounts
{
if
item
.
RateMultiplier
!=
nil
&&
*
item
.
RateMultiplier
<
0
{
...
...
@@ -1196,6 +1208,15 @@ func (h *AccountHandler) BatchCreate(c *gin.Context) {
})
continue
}
// 收集需要异步设置隐私的 OAuth 账号
if
account
.
Type
==
service
.
AccountTypeOAuth
{
switch
account
.
Platform
{
case
service
.
PlatformAntigravity
:
antigravityPrivacyAccounts
=
append
(
antigravityPrivacyAccounts
,
account
)
case
service
.
PlatformOpenAI
:
openaiPrivacyAccounts
=
append
(
openaiPrivacyAccounts
,
account
)
}
}
success
++
results
=
append
(
results
,
gin
.
H
{
"name"
:
item
.
Name
,
...
...
@@ -1204,6 +1225,37 @@ func (h *AccountHandler) BatchCreate(c *gin.Context) {
})
}
// 异步设置隐私,避免批量创建时阻塞请求
adminSvc
:=
h
.
adminService
if
len
(
antigravityPrivacyAccounts
)
>
0
{
accounts
:=
antigravityPrivacyAccounts
go
func
()
{
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
slog
.
Error
(
"batch_create_antigravity_privacy_panic"
,
"recover"
,
r
)
}
}()
bgCtx
:=
context
.
Background
()
for
_
,
acc
:=
range
accounts
{
adminSvc
.
ForceAntigravityPrivacy
(
bgCtx
,
acc
)
}
}()
}
if
len
(
openaiPrivacyAccounts
)
>
0
{
accounts
:=
openaiPrivacyAccounts
go
func
()
{
defer
func
()
{
if
r
:=
recover
();
r
!=
nil
{
slog
.
Error
(
"batch_create_openai_privacy_panic"
,
"recover"
,
r
)
}
}()
bgCtx
:=
context
.
Background
()
for
_
,
acc
:=
range
accounts
{
adminSvc
.
ForceOpenAIPrivacy
(
bgCtx
,
acc
)
}
}()
}
return
gin
.
H
{
"success"
:
success
,
"failed"
:
failed
,
...
...
@@ -1869,6 +1921,51 @@ func (h *AccountHandler) GetAvailableModels(c *gin.Context) {
response
.
Success
(
c
,
models
)
}
// SetPrivacy handles setting privacy for a single OpenAI/Antigravity OAuth account
// POST /api/v1/admin/accounts/:id/set-privacy
func
(
h
*
AccountHandler
)
SetPrivacy
(
c
*
gin
.
Context
)
{
accountID
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid account ID"
)
return
}
account
,
err
:=
h
.
adminService
.
GetAccount
(
c
.
Request
.
Context
(),
accountID
)
if
err
!=
nil
{
response
.
NotFound
(
c
,
"Account not found"
)
return
}
if
account
.
Type
!=
service
.
AccountTypeOAuth
{
response
.
BadRequest
(
c
,
"Only OAuth accounts support privacy setting"
)
return
}
var
mode
string
switch
account
.
Platform
{
case
service
.
PlatformOpenAI
:
mode
=
h
.
adminService
.
ForceOpenAIPrivacy
(
c
.
Request
.
Context
(),
account
)
case
service
.
PlatformAntigravity
:
mode
=
h
.
adminService
.
ForceAntigravityPrivacy
(
c
.
Request
.
Context
(),
account
)
default
:
response
.
BadRequest
(
c
,
"Only OpenAI and Antigravity OAuth accounts support privacy setting"
)
return
}
if
mode
==
""
{
response
.
BadRequest
(
c
,
"Cannot set privacy: missing access_token"
)
return
}
// 从 DB 重新读取以确保返回最新状态
updated
,
err
:=
h
.
adminService
.
GetAccount
(
c
.
Request
.
Context
(),
accountID
)
if
err
!=
nil
{
// 隐私已设置成功但读取失败,回退到内存更新
if
account
.
Extra
==
nil
{
account
.
Extra
=
make
(
map
[
string
]
any
)
}
account
.
Extra
[
"privacy_mode"
]
=
mode
response
.
Success
(
c
,
h
.
buildAccountResponseWithRuntime
(
c
.
Request
.
Context
(),
account
))
return
}
response
.
Success
(
c
,
h
.
buildAccountResponseWithRuntime
(
c
.
Request
.
Context
(),
updated
))
}
// RefreshTier handles refreshing Google One tier for a single account
// POST /api/v1/admin/accounts/:id/refresh-tier
func
(
h
*
AccountHandler
)
RefreshTier
(
c
*
gin
.
Context
)
{
...
...
backend/internal/handler/admin/admin_service_stub_test.go
View file @
b6d46fd5
...
...
@@ -445,6 +445,18 @@ func (s *stubAdminService) EnsureOpenAIPrivacy(ctx context.Context, account *ser
return
""
}
func
(
s
*
stubAdminService
)
EnsureAntigravityPrivacy
(
ctx
context
.
Context
,
account
*
service
.
Account
)
string
{
return
""
}
func
(
s
*
stubAdminService
)
ForceOpenAIPrivacy
(
ctx
context
.
Context
,
account
*
service
.
Account
)
string
{
return
""
}
func
(
s
*
stubAdminService
)
ForceAntigravityPrivacy
(
ctx
context
.
Context
,
account
*
service
.
Account
)
string
{
return
""
}
func
(
s
*
stubAdminService
)
ReplaceUserGroup
(
ctx
context
.
Context
,
userID
,
oldGroupID
,
newGroupID
int64
)
(
*
service
.
ReplaceUserGroupResult
,
error
)
{
return
&
service
.
ReplaceUserGroupResult
{
MigratedKeys
:
0
},
nil
}
...
...
backend/internal/handler/admin/setting_handler.go
View file @
b6d46fd5
...
...
@@ -129,6 +129,8 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
MaxClaudeCodeVersion
:
settings
.
MaxClaudeCodeVersion
,
AllowUngroupedKeyScheduling
:
settings
.
AllowUngroupedKeyScheduling
,
BackendModeEnabled
:
settings
.
BackendModeEnabled
,
EnableFingerprintUnification
:
settings
.
EnableFingerprintUnification
,
EnableMetadataPassthrough
:
settings
.
EnableMetadataPassthrough
,
})
}
...
...
@@ -209,6 +211,10 @@ type UpdateSettingsRequest struct {
// Backend Mode
BackendModeEnabled
bool
`json:"backend_mode_enabled"`
// Gateway forwarding behavior
EnableFingerprintUnification
*
bool
`json:"enable_fingerprint_unification"`
EnableMetadataPassthrough
*
bool
`json:"enable_metadata_passthrough"`
}
// UpdateSettings 更新系统设置
...
...
@@ -601,6 +607,18 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
}
return
previousSettings
.
OpsMetricsIntervalSeconds
}(),
EnableFingerprintUnification
:
func
()
bool
{
if
req
.
EnableFingerprintUnification
!=
nil
{
return
*
req
.
EnableFingerprintUnification
}
return
previousSettings
.
EnableFingerprintUnification
}(),
EnableMetadataPassthrough
:
func
()
bool
{
if
req
.
EnableMetadataPassthrough
!=
nil
{
return
*
req
.
EnableMetadataPassthrough
}
return
previousSettings
.
EnableMetadataPassthrough
}(),
}
if
err
:=
h
.
settingService
.
UpdateSettings
(
c
.
Request
.
Context
(),
settings
);
err
!=
nil
{
...
...
@@ -679,6 +697,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
MaxClaudeCodeVersion
:
updatedSettings
.
MaxClaudeCodeVersion
,
AllowUngroupedKeyScheduling
:
updatedSettings
.
AllowUngroupedKeyScheduling
,
BackendModeEnabled
:
updatedSettings
.
BackendModeEnabled
,
EnableFingerprintUnification
:
updatedSettings
.
EnableFingerprintUnification
,
EnableMetadataPassthrough
:
updatedSettings
.
EnableMetadataPassthrough
,
})
}
...
...
@@ -851,6 +871,12 @@ func diffSettings(before *service.SystemSettings, after *service.SystemSettings,
if
before
.
CustomMenuItems
!=
after
.
CustomMenuItems
{
changed
=
append
(
changed
,
"custom_menu_items"
)
}
if
before
.
EnableFingerprintUnification
!=
after
.
EnableFingerprintUnification
{
changed
=
append
(
changed
,
"enable_fingerprint_unification"
)
}
if
before
.
EnableMetadataPassthrough
!=
after
.
EnableMetadataPassthrough
{
changed
=
append
(
changed
,
"enable_metadata_passthrough"
)
}
return
changed
}
...
...
@@ -1568,18 +1594,26 @@ func (h *SettingHandler) GetRectifierSettings(c *gin.Context) {
return
}
patterns
:=
settings
.
APIKeySignaturePatterns
if
patterns
==
nil
{
patterns
=
[]
string
{}
}
response
.
Success
(
c
,
dto
.
RectifierSettings
{
Enabled
:
settings
.
Enabled
,
ThinkingSignatureEnabled
:
settings
.
ThinkingSignatureEnabled
,
ThinkingBudgetEnabled
:
settings
.
ThinkingBudgetEnabled
,
APIKeySignatureEnabled
:
settings
.
APIKeySignatureEnabled
,
APIKeySignaturePatterns
:
patterns
,
})
}
// UpdateRectifierSettingsRequest 更新整流器配置请求
type
UpdateRectifierSettingsRequest
struct
{
Enabled
bool
`json:"enabled"`
ThinkingSignatureEnabled
bool
`json:"thinking_signature_enabled"`
ThinkingBudgetEnabled
bool
`json:"thinking_budget_enabled"`
Enabled
bool
`json:"enabled"`
ThinkingSignatureEnabled
bool
`json:"thinking_signature_enabled"`
ThinkingBudgetEnabled
bool
`json:"thinking_budget_enabled"`
APIKeySignatureEnabled
bool
`json:"apikey_signature_enabled"`
APIKeySignaturePatterns
[]
string
`json:"apikey_signature_patterns"`
}
// UpdateRectifierSettings 更新请求整流器配置
...
...
@@ -1591,10 +1625,32 @@ func (h *SettingHandler) UpdateRectifierSettings(c *gin.Context) {
return
}
// 校验并清理自定义匹配关键词
const
maxPatterns
=
50
const
maxPatternLen
=
500
if
len
(
req
.
APIKeySignaturePatterns
)
>
maxPatterns
{
response
.
BadRequest
(
c
,
"Too many signature patterns (max 50)"
)
return
}
var
cleanedPatterns
[]
string
for
_
,
p
:=
range
req
.
APIKeySignaturePatterns
{
p
=
strings
.
TrimSpace
(
p
)
if
p
==
""
{
continue
}
if
len
(
p
)
>
maxPatternLen
{
response
.
BadRequest
(
c
,
"Signature pattern too long (max 500 characters)"
)
return
}
cleanedPatterns
=
append
(
cleanedPatterns
,
p
)
}
settings
:=
&
service
.
RectifierSettings
{
Enabled
:
req
.
Enabled
,
ThinkingSignatureEnabled
:
req
.
ThinkingSignatureEnabled
,
ThinkingBudgetEnabled
:
req
.
ThinkingBudgetEnabled
,
APIKeySignatureEnabled
:
req
.
APIKeySignatureEnabled
,
APIKeySignaturePatterns
:
cleanedPatterns
,
}
if
err
:=
h
.
settingService
.
SetRectifierSettings
(
c
.
Request
.
Context
(),
settings
);
err
!=
nil
{
...
...
@@ -1609,10 +1665,16 @@ func (h *SettingHandler) UpdateRectifierSettings(c *gin.Context) {
return
}
updatedPatterns
:=
updatedSettings
.
APIKeySignaturePatterns
if
updatedPatterns
==
nil
{
updatedPatterns
=
[]
string
{}
}
response
.
Success
(
c
,
dto
.
RectifierSettings
{
Enabled
:
updatedSettings
.
Enabled
,
ThinkingSignatureEnabled
:
updatedSettings
.
ThinkingSignatureEnabled
,
ThinkingBudgetEnabled
:
updatedSettings
.
ThinkingBudgetEnabled
,
APIKeySignatureEnabled
:
updatedSettings
.
APIKeySignatureEnabled
,
APIKeySignaturePatterns
:
updatedPatterns
,
})
}
...
...
backend/internal/handler/admin/tls_fingerprint_profile_handler.go
0 → 100644
View file @
b6d46fd5
package
admin
import
(
"strconv"
"github.com/Wei-Shaw/sub2api/internal/model"
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/gin-gonic/gin"
)
// TLSFingerprintProfileHandler 处理 TLS 指纹模板的 HTTP 请求
type
TLSFingerprintProfileHandler
struct
{
service
*
service
.
TLSFingerprintProfileService
}
// NewTLSFingerprintProfileHandler 创建 TLS 指纹模板处理器
func
NewTLSFingerprintProfileHandler
(
service
*
service
.
TLSFingerprintProfileService
)
*
TLSFingerprintProfileHandler
{
return
&
TLSFingerprintProfileHandler
{
service
:
service
}
}
// CreateTLSFingerprintProfileRequest 创建模板请求
type
CreateTLSFingerprintProfileRequest
struct
{
Name
string
`json:"name" binding:"required"`
Description
*
string
`json:"description"`
EnableGREASE
*
bool
`json:"enable_grease"`
CipherSuites
[]
uint16
`json:"cipher_suites"`
Curves
[]
uint16
`json:"curves"`
PointFormats
[]
uint16
`json:"point_formats"`
SignatureAlgorithms
[]
uint16
`json:"signature_algorithms"`
ALPNProtocols
[]
string
`json:"alpn_protocols"`
SupportedVersions
[]
uint16
`json:"supported_versions"`
KeyShareGroups
[]
uint16
`json:"key_share_groups"`
PSKModes
[]
uint16
`json:"psk_modes"`
Extensions
[]
uint16
`json:"extensions"`
}
// UpdateTLSFingerprintProfileRequest 更新模板请求(部分更新)
type
UpdateTLSFingerprintProfileRequest
struct
{
Name
*
string
`json:"name"`
Description
*
string
`json:"description"`
EnableGREASE
*
bool
`json:"enable_grease"`
CipherSuites
[]
uint16
`json:"cipher_suites"`
Curves
[]
uint16
`json:"curves"`
PointFormats
[]
uint16
`json:"point_formats"`
SignatureAlgorithms
[]
uint16
`json:"signature_algorithms"`
ALPNProtocols
[]
string
`json:"alpn_protocols"`
SupportedVersions
[]
uint16
`json:"supported_versions"`
KeyShareGroups
[]
uint16
`json:"key_share_groups"`
PSKModes
[]
uint16
`json:"psk_modes"`
Extensions
[]
uint16
`json:"extensions"`
}
// List 获取所有模板
// GET /api/v1/admin/tls-fingerprint-profiles
func
(
h
*
TLSFingerprintProfileHandler
)
List
(
c
*
gin
.
Context
)
{
profiles
,
err
:=
h
.
service
.
List
(
c
.
Request
.
Context
())
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
profiles
)
}
// GetByID 根据 ID 获取模板
// GET /api/v1/admin/tls-fingerprint-profiles/:id
func
(
h
*
TLSFingerprintProfileHandler
)
GetByID
(
c
*
gin
.
Context
)
{
id
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid profile ID"
)
return
}
profile
,
err
:=
h
.
service
.
GetByID
(
c
.
Request
.
Context
(),
id
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
if
profile
==
nil
{
response
.
NotFound
(
c
,
"Profile not found"
)
return
}
response
.
Success
(
c
,
profile
)
}
// Create 创建模板
// POST /api/v1/admin/tls-fingerprint-profiles
func
(
h
*
TLSFingerprintProfileHandler
)
Create
(
c
*
gin
.
Context
)
{
var
req
CreateTLSFingerprintProfileRequest
if
err
:=
c
.
ShouldBindJSON
(
&
req
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
profile
:=
&
model
.
TLSFingerprintProfile
{
Name
:
req
.
Name
,
Description
:
req
.
Description
,
CipherSuites
:
req
.
CipherSuites
,
Curves
:
req
.
Curves
,
PointFormats
:
req
.
PointFormats
,
SignatureAlgorithms
:
req
.
SignatureAlgorithms
,
ALPNProtocols
:
req
.
ALPNProtocols
,
SupportedVersions
:
req
.
SupportedVersions
,
KeyShareGroups
:
req
.
KeyShareGroups
,
PSKModes
:
req
.
PSKModes
,
Extensions
:
req
.
Extensions
,
}
if
req
.
EnableGREASE
!=
nil
{
profile
.
EnableGREASE
=
*
req
.
EnableGREASE
}
created
,
err
:=
h
.
service
.
Create
(
c
.
Request
.
Context
(),
profile
)
if
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
model
.
ValidationError
);
ok
{
response
.
BadRequest
(
c
,
err
.
Error
())
return
}
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
created
)
}
// Update 更新模板(支持部分更新)
// PUT /api/v1/admin/tls-fingerprint-profiles/:id
func
(
h
*
TLSFingerprintProfileHandler
)
Update
(
c
*
gin
.
Context
)
{
id
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid profile ID"
)
return
}
var
req
UpdateTLSFingerprintProfileRequest
if
err
:=
c
.
ShouldBindJSON
(
&
req
);
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid request: "
+
err
.
Error
())
return
}
existing
,
err
:=
h
.
service
.
GetByID
(
c
.
Request
.
Context
(),
id
)
if
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
if
existing
==
nil
{
response
.
NotFound
(
c
,
"Profile not found"
)
return
}
// 部分更新
profile
:=
&
model
.
TLSFingerprintProfile
{
ID
:
id
,
Name
:
existing
.
Name
,
Description
:
existing
.
Description
,
EnableGREASE
:
existing
.
EnableGREASE
,
CipherSuites
:
existing
.
CipherSuites
,
Curves
:
existing
.
Curves
,
PointFormats
:
existing
.
PointFormats
,
SignatureAlgorithms
:
existing
.
SignatureAlgorithms
,
ALPNProtocols
:
existing
.
ALPNProtocols
,
SupportedVersions
:
existing
.
SupportedVersions
,
KeyShareGroups
:
existing
.
KeyShareGroups
,
PSKModes
:
existing
.
PSKModes
,
Extensions
:
existing
.
Extensions
,
}
if
req
.
Name
!=
nil
{
profile
.
Name
=
*
req
.
Name
}
if
req
.
Description
!=
nil
{
profile
.
Description
=
req
.
Description
}
if
req
.
EnableGREASE
!=
nil
{
profile
.
EnableGREASE
=
*
req
.
EnableGREASE
}
if
req
.
CipherSuites
!=
nil
{
profile
.
CipherSuites
=
req
.
CipherSuites
}
if
req
.
Curves
!=
nil
{
profile
.
Curves
=
req
.
Curves
}
if
req
.
PointFormats
!=
nil
{
profile
.
PointFormats
=
req
.
PointFormats
}
if
req
.
SignatureAlgorithms
!=
nil
{
profile
.
SignatureAlgorithms
=
req
.
SignatureAlgorithms
}
if
req
.
ALPNProtocols
!=
nil
{
profile
.
ALPNProtocols
=
req
.
ALPNProtocols
}
if
req
.
SupportedVersions
!=
nil
{
profile
.
SupportedVersions
=
req
.
SupportedVersions
}
if
req
.
KeyShareGroups
!=
nil
{
profile
.
KeyShareGroups
=
req
.
KeyShareGroups
}
if
req
.
PSKModes
!=
nil
{
profile
.
PSKModes
=
req
.
PSKModes
}
if
req
.
Extensions
!=
nil
{
profile
.
Extensions
=
req
.
Extensions
}
updated
,
err
:=
h
.
service
.
Update
(
c
.
Request
.
Context
(),
profile
)
if
err
!=
nil
{
if
_
,
ok
:=
err
.
(
*
model
.
ValidationError
);
ok
{
response
.
BadRequest
(
c
,
err
.
Error
())
return
}
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
updated
)
}
// Delete 删除模板
// DELETE /api/v1/admin/tls-fingerprint-profiles/:id
func
(
h
*
TLSFingerprintProfileHandler
)
Delete
(
c
*
gin
.
Context
)
{
id
,
err
:=
strconv
.
ParseInt
(
c
.
Param
(
"id"
),
10
,
64
)
if
err
!=
nil
{
response
.
BadRequest
(
c
,
"Invalid profile ID"
)
return
}
if
err
:=
h
.
service
.
Delete
(
c
.
Request
.
Context
(),
id
);
err
!=
nil
{
response
.
ErrorFrom
(
c
,
err
)
return
}
response
.
Success
(
c
,
gin
.
H
{
"message"
:
"Profile deleted successfully"
})
}
backend/internal/handler/dto/mappers.go
View file @
b6d46fd5
...
...
@@ -252,6 +252,10 @@ func AccountFromServiceShallow(a *service.Account) *Account {
enabled
:=
true
out
.
EnableTLSFingerprint
=
&
enabled
}
// TLS指纹模板ID
if
profileID
:=
a
.
GetTLSFingerprintProfileID
();
profileID
>
0
{
out
.
TLSFingerprintProfileID
=
&
profileID
}
// 会话ID伪装开关
if
a
.
IsSessionIDMaskingEnabled
()
{
enabled
:=
true
...
...
backend/internal/handler/dto/settings.go
View file @
b6d46fd5
...
...
@@ -94,6 +94,10 @@ type SystemSettings struct {
// Backend Mode
BackendModeEnabled
bool
`json:"backend_mode_enabled"`
// Gateway forwarding behavior
EnableFingerprintUnification
bool
`json:"enable_fingerprint_unification"`
EnableMetadataPassthrough
bool
`json:"enable_metadata_passthrough"`
}
type
DefaultSubscriptionSetting
struct
{
...
...
@@ -184,9 +188,11 @@ type StreamTimeoutSettings struct {
// RectifierSettings 请求整流器配置 DTO
type
RectifierSettings
struct
{
Enabled
bool
`json:"enabled"`
ThinkingSignatureEnabled
bool
`json:"thinking_signature_enabled"`
ThinkingBudgetEnabled
bool
`json:"thinking_budget_enabled"`
Enabled
bool
`json:"enabled"`
ThinkingSignatureEnabled
bool
`json:"thinking_signature_enabled"`
ThinkingBudgetEnabled
bool
`json:"thinking_budget_enabled"`
APIKeySignatureEnabled
bool
`json:"apikey_signature_enabled"`
APIKeySignaturePatterns
[]
string
`json:"apikey_signature_patterns"`
}
// BetaPolicyRule Beta 策略规则 DTO
...
...
backend/internal/handler/dto/types.go
View file @
b6d46fd5
...
...
@@ -185,7 +185,8 @@ type Account struct {
// TLS指纹伪装(仅 Anthropic OAuth/SetupToken 账号有效)
// 从 extra 字段提取,方便前端显示和编辑
EnableTLSFingerprint
*
bool
`json:"enable_tls_fingerprint,omitempty"`
EnableTLSFingerprint
*
bool
`json:"enable_tls_fingerprint,omitempty"`
TLSFingerprintProfileID
*
int64
`json:"tls_fingerprint_profile_id,omitempty"`
// 会话ID伪装(仅 Anthropic OAuth/SetupToken 账号有效)
// 启用后将在15分钟内固定 metadata.user_id 中的 session ID
...
...
backend/internal/handler/gateway_handler.go
View file @
b6d46fd5
...
...
@@ -422,11 +422,24 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
}
}
wroteFallback
:=
h
.
ensureForwardErrorResponse
(
c
,
streamStarted
)
reqLog
.
Error
(
"gateway.
forward
_f
ailed
"
,
forward
F
ailed
Fields
:=
[]
zap
.
Field
{
zap
.
Int64
(
"account_id"
,
account
.
ID
),
zap
.
String
(
"account_name"
,
account
.
Name
),
zap
.
String
(
"account_platform"
,
account
.
Platform
),
zap
.
Bool
(
"fallback_error_response_written"
,
wroteFallback
),
zap
.
Error
(
err
),
)
}
if
account
.
Proxy
!=
nil
{
forwardFailedFields
=
append
(
forwardFailedFields
,
zap
.
Int64
(
"proxy_id"
,
account
.
Proxy
.
ID
),
zap
.
String
(
"proxy_name"
,
account
.
Proxy
.
Name
),
zap
.
String
(
"proxy_host"
,
account
.
Proxy
.
Host
),
zap
.
Int
(
"proxy_port"
,
account
.
Proxy
.
Port
),
)
}
else
if
account
.
ProxyID
!=
nil
{
forwardFailedFields
=
append
(
forwardFailedFields
,
zap
.
Int64p
(
"proxy_id"
,
account
.
ProxyID
))
}
reqLog
.
Error
(
"gateway.forward_failed"
,
forwardFailedFields
...
)
return
}
...
...
@@ -741,11 +754,24 @@ func (h *GatewayHandler) Messages(c *gin.Context) {
}
}
wroteFallback
:=
h
.
ensureForwardErrorResponse
(
c
,
streamStarted
)
reqLog
.
Error
(
"gateway.
forward
_f
ailed
"
,
forward
F
ailed
Fields
:=
[]
zap
.
Field
{
zap
.
Int64
(
"account_id"
,
account
.
ID
),
zap
.
String
(
"account_name"
,
account
.
Name
),
zap
.
String
(
"account_platform"
,
account
.
Platform
),
zap
.
Bool
(
"fallback_error_response_written"
,
wroteFallback
),
zap
.
Error
(
err
),
)
}
if
account
.
Proxy
!=
nil
{
forwardFailedFields
=
append
(
forwardFailedFields
,
zap
.
Int64
(
"proxy_id"
,
account
.
Proxy
.
ID
),
zap
.
String
(
"proxy_name"
,
account
.
Proxy
.
Name
),
zap
.
String
(
"proxy_host"
,
account
.
Proxy
.
Host
),
zap
.
Int
(
"proxy_port"
,
account
.
Proxy
.
Port
),
)
}
else
if
account
.
ProxyID
!=
nil
{
forwardFailedFields
=
append
(
forwardFailedFields
,
zap
.
Int64p
(
"proxy_id"
,
account
.
ProxyID
))
}
reqLog
.
Error
(
"gateway.forward_failed"
,
forwardFailedFields
...
)
return
}
...
...
backend/internal/handler/gateway_handler_warmup_intercept_unit_test.go
View file @
b6d46fd5
...
...
@@ -75,8 +75,10 @@ func (f *fakeGroupRepo) ListActive(context.Context) ([]service.Group, error) { r
func
(
f
*
fakeGroupRepo
)
ListActiveByPlatform
(
context
.
Context
,
string
)
([]
service
.
Group
,
error
)
{
return
nil
,
nil
}
func
(
f
*
fakeGroupRepo
)
ExistsByName
(
context
.
Context
,
string
)
(
bool
,
error
)
{
return
false
,
nil
}
func
(
f
*
fakeGroupRepo
)
GetAccountCount
(
context
.
Context
,
int64
)
(
int64
,
int64
,
error
)
{
return
0
,
0
,
nil
}
func
(
f
*
fakeGroupRepo
)
ExistsByName
(
context
.
Context
,
string
)
(
bool
,
error
)
{
return
false
,
nil
}
func
(
f
*
fakeGroupRepo
)
GetAccountCount
(
context
.
Context
,
int64
)
(
int64
,
int64
,
error
)
{
return
0
,
0
,
nil
}
func
(
f
*
fakeGroupRepo
)
DeleteAccountGroupsByGroupID
(
context
.
Context
,
int64
)
(
int64
,
error
)
{
return
0
,
nil
}
...
...
@@ -158,6 +160,7 @@ func newTestGatewayHandler(t *testing.T, group *service.Group, accounts []*servi
nil
,
// rpmCache
nil
,
// digestStore
nil
,
// settingService
nil
,
// tlsFPProfileService
)
// RunModeSimple:跳过计费检查,避免引入 repo/cache 依赖。
...
...
backend/internal/handler/handler.go
View file @
b6d46fd5
...
...
@@ -6,29 +6,30 @@ import (
// AdminHandlers contains all admin-related HTTP handlers
type
AdminHandlers
struct
{
Dashboard
*
admin
.
DashboardHandler
User
*
admin
.
UserHandler
Group
*
admin
.
GroupHandler
Account
*
admin
.
AccountHandler
Announcement
*
admin
.
AnnouncementHandler
DataManagement
*
admin
.
DataManagementHandler
Backup
*
admin
.
BackupHandler
OAuth
*
admin
.
OAuthHandler
OpenAIOAuth
*
admin
.
OpenAIOAuthHandler
GeminiOAuth
*
admin
.
GeminiOAuthHandler
AntigravityOAuth
*
admin
.
AntigravityOAuthHandler
Proxy
*
admin
.
ProxyHandler
Redeem
*
admin
.
RedeemHandler
Promo
*
admin
.
PromoHandler
Setting
*
admin
.
SettingHandler
Ops
*
admin
.
OpsHandler
System
*
admin
.
SystemHandler
Subscription
*
admin
.
SubscriptionHandler
Usage
*
admin
.
UsageHandler
UserAttribute
*
admin
.
UserAttributeHandler
ErrorPassthrough
*
admin
.
ErrorPassthroughHandler
APIKey
*
admin
.
AdminAPIKeyHandler
ScheduledTest
*
admin
.
ScheduledTestHandler
Dashboard
*
admin
.
DashboardHandler
User
*
admin
.
UserHandler
Group
*
admin
.
GroupHandler
Account
*
admin
.
AccountHandler
Announcement
*
admin
.
AnnouncementHandler
DataManagement
*
admin
.
DataManagementHandler
Backup
*
admin
.
BackupHandler
OAuth
*
admin
.
OAuthHandler
OpenAIOAuth
*
admin
.
OpenAIOAuthHandler
GeminiOAuth
*
admin
.
GeminiOAuthHandler
AntigravityOAuth
*
admin
.
AntigravityOAuthHandler
Proxy
*
admin
.
ProxyHandler
Redeem
*
admin
.
RedeemHandler
Promo
*
admin
.
PromoHandler
Setting
*
admin
.
SettingHandler
Ops
*
admin
.
OpsHandler
System
*
admin
.
SystemHandler
Subscription
*
admin
.
SubscriptionHandler
Usage
*
admin
.
UsageHandler
UserAttribute
*
admin
.
UserAttributeHandler
ErrorPassthrough
*
admin
.
ErrorPassthroughHandler
TLSFingerprintProfile
*
admin
.
TLSFingerprintProfileHandler
APIKey
*
admin
.
AdminAPIKeyHandler
ScheduledTest
*
admin
.
ScheduledTestHandler
}
// Handlers contains all HTTP handlers
...
...
backend/internal/handler/sora_client_handler_test.go
View file @
b6d46fd5
...
...
@@ -2224,7 +2224,7 @@ func (s *stubSoraClientForHandler) GetVideoTask(_ context.Context, _ *service.Ac
func
newMinimalGatewayService
(
accountRepo
service
.
AccountRepository
)
*
service
.
GatewayService
{
return
service
.
NewGatewayService
(
accountRepo
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
nil
,
)
}
...
...
backend/internal/handler/sora_gateway_handler_test.go
View file @
b6d46fd5
...
...
@@ -464,6 +464,7 @@ func TestSoraGatewayHandler_ChatCompletions(t *testing.T) {
nil
,
// rpmCache
nil
,
// digestStore
nil
,
// settingService
nil
,
// tlsFPProfileService
)
soraClient
:=
&
stubSoraClient
{
imageURLs
:
[]
string
{
"https://example.com/a.png"
}}
...
...
backend/internal/handler/wire.go
View file @
b6d46fd5
...
...
@@ -30,33 +30,35 @@ func ProvideAdminHandlers(
usageHandler
*
admin
.
UsageHandler
,
userAttributeHandler
*
admin
.
UserAttributeHandler
,
errorPassthroughHandler
*
admin
.
ErrorPassthroughHandler
,
tlsFingerprintProfileHandler
*
admin
.
TLSFingerprintProfileHandler
,
apiKeyHandler
*
admin
.
AdminAPIKeyHandler
,
scheduledTestHandler
*
admin
.
ScheduledTestHandler
,
)
*
AdminHandlers
{
return
&
AdminHandlers
{
Dashboard
:
dashboardHandler
,
User
:
userHandler
,
Group
:
groupHandler
,
Account
:
accountHandler
,
Announcement
:
announcementHandler
,
DataManagement
:
dataManagementHandler
,
Backup
:
backupHandler
,
OAuth
:
oauthHandler
,
OpenAIOAuth
:
openaiOAuthHandler
,
GeminiOAuth
:
geminiOAuthHandler
,
AntigravityOAuth
:
antigravityOAuthHandler
,
Proxy
:
proxyHandler
,
Redeem
:
redeemHandler
,
Promo
:
promoHandler
,
Setting
:
settingHandler
,
Ops
:
opsHandler
,
System
:
systemHandler
,
Subscription
:
subscriptionHandler
,
Usage
:
usageHandler
,
UserAttribute
:
userAttributeHandler
,
ErrorPassthrough
:
errorPassthroughHandler
,
APIKey
:
apiKeyHandler
,
ScheduledTest
:
scheduledTestHandler
,
Dashboard
:
dashboardHandler
,
User
:
userHandler
,
Group
:
groupHandler
,
Account
:
accountHandler
,
Announcement
:
announcementHandler
,
DataManagement
:
dataManagementHandler
,
Backup
:
backupHandler
,
OAuth
:
oauthHandler
,
OpenAIOAuth
:
openaiOAuthHandler
,
GeminiOAuth
:
geminiOAuthHandler
,
AntigravityOAuth
:
antigravityOAuthHandler
,
Proxy
:
proxyHandler
,
Redeem
:
redeemHandler
,
Promo
:
promoHandler
,
Setting
:
settingHandler
,
Ops
:
opsHandler
,
System
:
systemHandler
,
Subscription
:
subscriptionHandler
,
Usage
:
usageHandler
,
UserAttribute
:
userAttributeHandler
,
ErrorPassthrough
:
errorPassthroughHandler
,
TLSFingerprintProfile
:
tlsFingerprintProfileHandler
,
APIKey
:
apiKeyHandler
,
ScheduledTest
:
scheduledTestHandler
,
}
}
...
...
@@ -145,6 +147,7 @@ var ProviderSet = wire.NewSet(
admin
.
NewUsageHandler
,
admin
.
NewUserAttributeHandler
,
admin
.
NewErrorPassthroughHandler
,
admin
.
NewTLSFingerprintProfileHandler
,
admin
.
NewAdminAPIKeyHandler
,
admin
.
NewScheduledTestHandler
,
...
...
backend/internal/model/tls_fingerprint_profile.go
0 → 100644
View file @
b6d46fd5
// Package model 定义服务层使用的数据模型。
package
model
import
(
"time"
"github.com/Wei-Shaw/sub2api/internal/pkg/tlsfingerprint"
)
// TLSFingerprintProfile TLS 指纹配置模板
// 包含完整的 ClientHello 参数,用于模拟特定客户端的 TLS 握手特征
type
TLSFingerprintProfile
struct
{
ID
int64
`json:"id"`
Name
string
`json:"name"`
Description
*
string
`json:"description"`
EnableGREASE
bool
`json:"enable_grease"`
CipherSuites
[]
uint16
`json:"cipher_suites"`
Curves
[]
uint16
`json:"curves"`
PointFormats
[]
uint16
`json:"point_formats"`
SignatureAlgorithms
[]
uint16
`json:"signature_algorithms"`
ALPNProtocols
[]
string
`json:"alpn_protocols"`
SupportedVersions
[]
uint16
`json:"supported_versions"`
KeyShareGroups
[]
uint16
`json:"key_share_groups"`
PSKModes
[]
uint16
`json:"psk_modes"`
Extensions
[]
uint16
`json:"extensions"`
CreatedAt
time
.
Time
`json:"created_at"`
UpdatedAt
time
.
Time
`json:"updated_at"`
}
// Validate 验证模板配置的有效性
func
(
p
*
TLSFingerprintProfile
)
Validate
()
error
{
if
p
.
Name
==
""
{
return
&
ValidationError
{
Field
:
"name"
,
Message
:
"name is required"
}
}
return
nil
}
// ToTLSProfile 将领域模型转换为运行时使用的 tlsfingerprint.Profile
// 空切片字段会在 dialer 中 fallback 到内置默认值
func
(
p
*
TLSFingerprintProfile
)
ToTLSProfile
()
*
tlsfingerprint
.
Profile
{
return
&
tlsfingerprint
.
Profile
{
Name
:
p
.
Name
,
EnableGREASE
:
p
.
EnableGREASE
,
CipherSuites
:
p
.
CipherSuites
,
Curves
:
p
.
Curves
,
PointFormats
:
p
.
PointFormats
,
SignatureAlgorithms
:
p
.
SignatureAlgorithms
,
ALPNProtocols
:
p
.
ALPNProtocols
,
SupportedVersions
:
p
.
SupportedVersions
,
KeyShareGroups
:
p
.
KeyShareGroups
,
PSKModes
:
p
.
PSKModes
,
Extensions
:
p
.
Extensions
,
}
}
backend/internal/pkg/antigravity/client.go
View file @
b6d46fd5
...
...
@@ -78,7 +78,9 @@ type UserInfo struct {
// LoadCodeAssistRequest loadCodeAssist 请求
type
LoadCodeAssistRequest
struct
{
Metadata
struct
{
IDEType
string
`json:"ideType"`
IDEType
string
`json:"ideType"`
IDEVersion
string
`json:"ideVersion"`
IDEName
string
`json:"ideName"`
}
`json:"metadata"`
}
...
...
@@ -223,6 +225,23 @@ func (r *LoadCodeAssistResponse) GetAvailableCredits() []AvailableCredit {
return
r
.
PaidTier
.
AvailableCredits
}
// TierIDToPlanType 将 tier ID 映射为用户可见的套餐名。
func
TierIDToPlanType
(
tierID
string
)
string
{
switch
strings
.
ToLower
(
strings
.
TrimSpace
(
tierID
))
{
case
"free-tier"
:
return
"Free"
case
"g1-pro-tier"
:
return
"Pro"
case
"g1-ultra-tier"
:
return
"Ultra"
default
:
if
tierID
==
""
{
return
"Free"
}
return
tierID
}
}
// Client Antigravity API 客户端
type
Client
struct
{
httpClient
*
http
.
Client
...
...
@@ -421,6 +440,8 @@ func (c *Client) GetUserInfo(ctx context.Context, accessToken string) (*UserInfo
func
(
c
*
Client
)
LoadCodeAssist
(
ctx
context
.
Context
,
accessToken
string
)
(
*
LoadCodeAssistResponse
,
map
[
string
]
any
,
error
)
{
reqBody
:=
LoadCodeAssistRequest
{}
reqBody
.
Metadata
.
IDEType
=
"ANTIGRAVITY"
reqBody
.
Metadata
.
IDEVersion
=
"1.20.6"
reqBody
.
Metadata
.
IDEName
=
"antigravity"
bodyBytes
,
err
:=
json
.
Marshal
(
reqBody
)
if
err
!=
nil
{
...
...
@@ -704,3 +725,139 @@ func (c *Client) FetchAvailableModels(ctx context.Context, accessToken, projectI
return
nil
,
nil
,
lastErr
}
// ── Privacy API ──────────────────────────────────────────────────────
// privacyBaseURL 隐私设置 API 仅使用 daily 端点(与 Antigravity 客户端行为一致)
const
privacyBaseURL
=
antigravityDailyBaseURL
// SetUserSettingsRequest setUserSettings 请求体
type
SetUserSettingsRequest
struct
{
UserSettings
map
[
string
]
any
`json:"user_settings"`
}
// FetchUserInfoRequest fetchUserInfo 请求体
type
FetchUserInfoRequest
struct
{
Project
string
`json:"project"`
}
// FetchUserInfoResponse fetchUserInfo 响应体
type
FetchUserInfoResponse
struct
{
UserSettings
map
[
string
]
any
`json:"userSettings,omitempty"`
RegionCode
string
`json:"regionCode,omitempty"`
}
// IsPrivate 判断隐私是否已设置:userSettings 为空或不含 telemetryEnabled 表示已设置
func
(
r
*
FetchUserInfoResponse
)
IsPrivate
()
bool
{
if
r
==
nil
||
r
.
UserSettings
==
nil
{
return
true
}
_
,
hasTelemetry
:=
r
.
UserSettings
[
"telemetryEnabled"
]
return
!
hasTelemetry
}
// SetUserSettingsResponse setUserSettings 响应体
type
SetUserSettingsResponse
struct
{
UserSettings
map
[
string
]
any
`json:"userSettings,omitempty"`
}
// IsSuccess 判断 setUserSettings 是否成功:返回 {"userSettings":{}} 且无 telemetryEnabled
func
(
r
*
SetUserSettingsResponse
)
IsSuccess
()
bool
{
if
r
==
nil
{
return
false
}
// userSettings 为 nil 或空 map 均视为成功
if
len
(
r
.
UserSettings
)
==
0
{
return
true
}
// 如果包含 telemetryEnabled 字段,说明未成功清除
_
,
hasTelemetry
:=
r
.
UserSettings
[
"telemetryEnabled"
]
return
!
hasTelemetry
}
// SetUserSettings 调用 setUserSettings API 设置用户隐私,返回解析后的响应
func
(
c
*
Client
)
SetUserSettings
(
ctx
context
.
Context
,
accessToken
string
)
(
*
SetUserSettingsResponse
,
error
)
{
// 发送空 user_settings 以清除隐私设置
payload
:=
SetUserSettingsRequest
{
UserSettings
:
map
[
string
]
any
{}}
bodyBytes
,
err
:=
json
.
Marshal
(
payload
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"序列化请求失败: %w"
,
err
)
}
apiURL
:=
privacyBaseURL
+
"/v1internal:setUserSettings"
req
,
err
:=
http
.
NewRequestWithContext
(
ctx
,
http
.
MethodPost
,
apiURL
,
bytes
.
NewReader
(
bodyBytes
))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"创建请求失败: %w"
,
err
)
}
req
.
Header
.
Set
(
"Authorization"
,
"Bearer "
+
accessToken
)
req
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
req
.
Header
.
Set
(
"Accept"
,
"*/*"
)
req
.
Header
.
Set
(
"User-Agent"
,
GetUserAgent
())
req
.
Header
.
Set
(
"X-Goog-Api-Client"
,
"gl-node/22.21.1"
)
req
.
Host
=
"daily-cloudcode-pa.googleapis.com"
resp
,
err
:=
c
.
httpClient
.
Do
(
req
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"setUserSettings 请求失败: %w"
,
err
)
}
defer
func
()
{
_
=
resp
.
Body
.
Close
()
}()
respBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"读取响应失败: %w"
,
err
)
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
return
nil
,
fmt
.
Errorf
(
"setUserSettings 失败 (HTTP %d): %s"
,
resp
.
StatusCode
,
string
(
respBody
))
}
var
result
SetUserSettingsResponse
if
err
:=
json
.
Unmarshal
(
respBody
,
&
result
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"响应解析失败: %w"
,
err
)
}
return
&
result
,
nil
}
// FetchUserInfo 调用 fetchUserInfo API 获取用户隐私设置状态
func
(
c
*
Client
)
FetchUserInfo
(
ctx
context
.
Context
,
accessToken
,
projectID
string
)
(
*
FetchUserInfoResponse
,
error
)
{
reqBody
:=
FetchUserInfoRequest
{
Project
:
projectID
}
bodyBytes
,
err
:=
json
.
Marshal
(
reqBody
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"序列化请求失败: %w"
,
err
)
}
apiURL
:=
privacyBaseURL
+
"/v1internal:fetchUserInfo"
req
,
err
:=
http
.
NewRequestWithContext
(
ctx
,
http
.
MethodPost
,
apiURL
,
bytes
.
NewReader
(
bodyBytes
))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"创建请求失败: %w"
,
err
)
}
req
.
Header
.
Set
(
"Authorization"
,
"Bearer "
+
accessToken
)
req
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
req
.
Header
.
Set
(
"Accept"
,
"*/*"
)
req
.
Header
.
Set
(
"User-Agent"
,
GetUserAgent
())
req
.
Header
.
Set
(
"X-Goog-Api-Client"
,
"gl-node/22.21.1"
)
req
.
Host
=
"daily-cloudcode-pa.googleapis.com"
resp
,
err
:=
c
.
httpClient
.
Do
(
req
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"fetchUserInfo 请求失败: %w"
,
err
)
}
defer
func
()
{
_
=
resp
.
Body
.
Close
()
}()
respBody
,
err
:=
io
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"读取响应失败: %w"
,
err
)
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
return
nil
,
fmt
.
Errorf
(
"fetchUserInfo 失败 (HTTP %d): %s"
,
resp
.
StatusCode
,
string
(
respBody
))
}
var
result
FetchUserInfoResponse
if
err
:=
json
.
Unmarshal
(
respBody
,
&
result
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"响应解析失败: %w"
,
err
)
}
return
&
result
,
nil
}
backend/internal/pkg/antigravity/client_test.go
View file @
b6d46fd5
...
...
@@ -250,6 +250,27 @@ func TestGetTier_两者都为nil(t *testing.T) {
}
}
func
TestTierIDToPlanType
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
tierID
string
want
string
}{
{
"free-tier"
,
"Free"
},
{
"g1-pro-tier"
,
"Pro"
},
{
"g1-ultra-tier"
,
"Ultra"
},
{
"FREE-TIER"
,
"Free"
},
{
""
,
"Free"
},
{
"unknown-tier"
,
"unknown-tier"
},
}
for
_
,
tt
:=
range
tests
{
t
.
Run
(
tt
.
tierID
,
func
(
t
*
testing
.
T
)
{
if
got
:=
TierIDToPlanType
(
tt
.
tierID
);
got
!=
tt
.
want
{
t
.
Errorf
(
"TierIDToPlanType(%q) = %q, want %q"
,
tt
.
tierID
,
got
,
tt
.
want
)
}
})
}
}
// ---------------------------------------------------------------------------
// NewClient
// ---------------------------------------------------------------------------
...
...
@@ -800,6 +821,12 @@ type redirectRoundTripper struct {
transport
http
.
RoundTripper
}
type
roundTripperFunc
func
(
*
http
.
Request
)
(
*
http
.
Response
,
error
)
func
(
f
roundTripperFunc
)
RoundTrip
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
return
f
(
req
)
}
func
(
rt
*
redirectRoundTripper
)
RoundTrip
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
originalURL
:=
req
.
URL
.
String
()
for
prefix
,
target
:=
range
rt
.
redirects
{
...
...
@@ -1271,6 +1298,12 @@ func TestClient_LoadCodeAssist_Success_RealCall(t *testing.T) {
if
reqBody
.
Metadata
.
IDEType
!=
"ANTIGRAVITY"
{
t
.
Errorf
(
"IDEType 不匹配: got %s, want ANTIGRAVITY"
,
reqBody
.
Metadata
.
IDEType
)
}
if
strings
.
TrimSpace
(
reqBody
.
Metadata
.
IDEVersion
)
==
""
{
t
.
Errorf
(
"IDEVersion 不应为空"
)
}
if
reqBody
.
Metadata
.
IDEName
!=
"antigravity"
{
t
.
Errorf
(
"IDEName 不匹配: got %s, want antigravity"
,
reqBody
.
Metadata
.
IDEName
)
}
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
w
.
WriteHeader
(
http
.
StatusOK
)
...
...
Prev
1
2
3
4
5
6
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment